Option type: Difference between revisions
DarthKitty (talk | contribs) m →Examples: use a more explicit name than "compute" (also fixes an issue in the Idris section where "compute" was highlighted as a keyword for some reason) |
→Zig: In Zig, add ? before the type name like <code>?32</code> to make it optional type. Payload <var>n</var> can be captured in an ''if'' or ''while'' statement, such as <syntaxhighlight lang=zig inline>if (opt) |n| { ... } else { ... } </syntaxhighlight>, and an |
||
Line 251: | Line 251: | ||
showValue(full) -> The value is: 42 |
showValue(full) -> The value is: 42 |
||
showValue(empty) -> No value |
showValue(empty) -> No value |
||
</syntaxhighlight> |
|||
=== Zig === |
|||
{{Further|Zig (programming language)}} |
|||
In Zig, add ? before the type name like <code>?32</code> to make it optional type. |
|||
Payload <var>n</var> can be captured in an ''if'' or ''while'' statement, such as <syntaxhighlight lang=zig inline>if (opt) |n| { ... } else { ... } </syntaxhighlight>, and an ''else'' clause is evaluated if it is <var>null</var>. |
|||
;Code example:<syntaxhighlight lang="zig"> |
|||
const std = @import("std"); |
|||
const print = std.io.getStdOut().writer().print; |
|||
const Compute = struct { |
|||
value: ?i32, |
|||
pub fn init(value: ?i32) Compute { |
|||
return Compute{ .value = value }; |
|||
} |
|||
pub fn format( |
|||
self: @This(), |
|||
comptime fmt: []const u8, |
|||
options: std.fmt.FormatOptions, |
|||
out_stream: anytype, |
|||
) !void { |
|||
_ = fmt; |
|||
_ = options; |
|||
if (self.value) |n| { |
|||
return out_stream.print("The value is: {}", .{n}); |
|||
} else { |
|||
return out_stream.print("No value", .{}); |
|||
} |
|||
} |
|||
}; |
|||
pub fn main() !void { |
|||
const full = Compute.init(42); |
|||
const empty = Compute.init(null); |
|||
try print("full -> {}\n", .{full}); |
|||
try print("empty -> {}\n", .{empty}); |
|||
} |
|||
</syntaxhighlight> |
|||
;Execution results:<syntaxhighlight lang="output"> |
|||
full -> The value is: 42 |
|||
empty -> No value |
|||
</syntaxhighlight> |
</syntaxhighlight> |
||
Revision as of 05:17, 26 September 2022
This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these messages)
|
In programming languages (especially functional programming languages) and type theory, an option type or maybe type is a polymorphic type that represents encapsulation of an optional value; e.g., it is used as the return type of functions which may or may not return a meaningful value when they are applied. It consists of a constructor which either is empty (often named None
or Nothing
), or which encapsulates the original data type A
(often written Just A
or Some A
).
A distinct, but related concept outside of functional programming, which is popular in object-oriented programming, is called nullable types (often expressed as A?
). The core difference between option types and nullable types is that option types support nesting (e.g. Maybe (Maybe String)
≠ Maybe String
), while nullable types do not (e.g. String??
= String?
).
Theoretical aspects
This section has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these messages)
|
In type theory, it may be written as: . This expresses the fact that for a given set of values in , an option type adds exactly one additional value (the empty value) to the set of valid values for . This is reflected in programming by the fact that in languages having tagged unions, option types can be expressed as the tagged union of the encapsulated type plus a unit type.[1]
In the Curry–Howard correspondence, option types are related to the annihilation law for ∨: x∨1=1.[how?]
An option type can also be seen as a collection containing either one or zero elements.[original research?]
The option type is also a monad where:[2]
return = Just -- Wraps the value into a maybe
Nothing >>= f = Nothing -- Fails if the previous monad fails
(Just x) >>= f = f x -- Succeeds when both monads succeed
The monadic nature of the option type is useful for efficiently tracking failure and errors.[3]
Examples
Agda
This section needs expansion with: example usage. You can help by adding to it. (July 2022) |
In Agda, the option type is named Maybe
with variants nothing
and just a
.
Coq
This section needs expansion with: example usage. You can help by adding to it. (July 2022) |
In Coq, the option type is defined as Inductive option (A:Type) : Type := | Some : A -> option A | None : option A.
.
Elm
This section needs expansion with: example usage. You can help by adding to it. (July 2022) |
In Elm, the option type is defined as type Maybe a = Just a | Nothing
.[4]
F#
This section needs expansion with: the definition. You can help by adding to it. (July 2022) |
let showValue =
Option.fold (fun _ x -> sprintf "The value is: %d" x) "No value"
let full = Some 42
let empty = None
showValue full |> printfn "showValue full -> %s"
showValue empty |> printfn "showValue empty -> %s"
showValue full -> The value is: 42
showValue empty -> No value
Haskell
In Haskell, the option type is defined as data Maybe a = Nothing | Just a
.[5]
showValue :: Maybe Int -> String
showValue = foldl (\_ x -> "The value is: " ++ show x) "No value"
main :: IO ()
main = do
let full = Just 42
let empty = Nothing
putStrLn $ "showValue full -> " ++ showValue full
putStrLn $ "showValue empty -> " ++ showValue empty
showValue full -> The value is: 42
showValue empty -> No value
Idris
In Idris, the option type is defined as data Maybe a = Nothing | Just a
.
showValue : Maybe Int -> String
showValue = foldl (\_, x => "The value is " ++ show x) "No value"
main : IO ()
main = do
let full = Just 42
let empty = Nothing
putStrLn $ "showValue full -> " ++ showValue full
putStrLn $ "showValue empty -> " ++ showValue empty
showValue full -> The value is: 42
showValue empty -> No value
Nim
This section needs expansion with: the definition. You can help by adding to it. (July 2022) |
import std/options
proc showValue(opt: Option[int]): string =
opt.map(proc (x: int): string = "The value is: " & $x).get("No value")
let
full = some(42)
empty = none(int)
echo "showValue(full) -> ", showValue(full)
echo "showValue(empty) -> ", showValue(empty)
showValue(full) -> The Value is: 42
showValue(empty) -> No value
OCaml
In OCaml, the option type is defined as type 'a option = None | Some of 'a
.[6]
let show_value =
Option.fold ~none:"No value" ~some:(fun x -> "The value is: " ^ string_of_int x)
let () =
let full = Some 42 in
let empty = None in
print_endline ("show_value full -> " ^ show_value full);
print_endline ("show_value empty -> " ^ show_value empty)
show_value full -> The value is: 42
show_value empty -> No value
Rust
In Rust, the option type is defined as enum Option<T> { None, Some(T) }
.[7]
fn show_value(opt: Option<i32>) -> String {
opt.map_or("No value".to_owned(), |x| format!("The value is: {}", x))
}
fn main() {
let full = Some(42);
let empty = None;
println!("show_value(full) -> {}", show_value(full));
println!("show_value(empty) -> {}", show_value(empty));
}
show_value(full) -> The value is: 42
show_value(empty) -> No value
Scala
In Scala, the option type is defined as sealed abstract class Option[+A]
, a type extended by final case class Some[+A](value: A)
and case object None
.
object Main {
def showValue(opt: Option[Int]): String =
opt.fold("No value")(x => s"The value is: $x")
def main(args: Array[String]): Unit = {
val full = Some(42)
val empty = None
println(s"showValue(full) -> ${showValue(full)}")
println(s"showValue(empty) -> ${showValue(empty)}")
}
}
showValue(full) -> The value is: 42
showValue(empty) -> No value
Standard ML
This section needs expansion with: example usage. You can help by adding to it. (July 2022) |
In Standard ML, the option type is defined as datatype 'a option = NONE | SOME of 'a
.
Swift
In Swift, the option type is defined as enum Optional<T> { case none, some(T) }
but is generally written as T?
.[8]
func showValue(_ opt: Int?) -> String {
return opt.map { "The value is: \($0)" } ?? "No value"
}
let full = 42
let empty: Int? = nil
print("showValue(full) -> \(showValue(full))")
print("showValue(empty) -> \(showValue(empty))")
showValue(full) -> The value is: 42
showValue(empty) -> No value
Zig
In Zig, add ? before the type name like ?32
to make it optional type.
Payload n can be captured in an if or while statement, such as if (opt) |n| { ... } else { ... }
, and an else clause is evaluated if it is null.
- Code example
const std = @import("std"); const print = std.io.getStdOut().writer().print; const Compute = struct { value: ?i32, pub fn init(value: ?i32) Compute { return Compute{ .value = value }; } pub fn format( self: @This(), comptime fmt: []const u8, options: std.fmt.FormatOptions, out_stream: anytype, ) !void { _ = fmt; _ = options; if (self.value) |n| { return out_stream.print("The value is: {}", .{n}); } else { return out_stream.print("No value", .{}); } } }; pub fn main() !void { const full = Compute.init(42); const empty = Compute.init(null); try print("full -> {}\n", .{full}); try print("empty -> {}\n", .{empty}); }
- Execution results
full -> The value is: 42 empty -> No value
See also
References
- ^ Milewski, Bartosz (2015-01-13). "Simple Algebraic Data Types". Bartosz Milewski's Programming Cafe. Sum types. "We could have encoded Maybe as: data Maybe a = Either () a". Archived from the original on 2019-08-18. Retrieved 2019-08-18.
- ^ "A Fistful of Monads - Learn You a Haskell for Great Good!". www.learnyouahaskell.com. Retrieved 2019-08-18.
- ^ Hutton, Graham (Nov 25, 2017). "What is a Monad?". Computerphile Youtube. Archived from the original on 2021-12-20. Retrieved Aug 18, 2019.
- ^ "Maybe · An Introduction to Elm". guide.elm-lang.org.
- ^ "6 Predefined Types and Classes". www.haskell.org. Retrieved 2022-06-15.
- ^ "OCaml library : Option". v2.ocaml.org. Retrieved 2022-06-15.
- ^ "Option in core::option - Rust". doc.rust-lang.org. 2022-05-18. Retrieved 2022-06-15.
- ^ "Apple Developer Documentation". developer.apple.com. Retrieved 2020-09-06.