Option type
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 A distinct, but related concept outside of functional programming, which is popular in object-oriented programming, is called nullable types (often expressed as Theoretical aspectsIn 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] An option type is a particular case of a tagged union, where the The option type is also a monad where:[3] 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.[4] ExamplesAdaAda does not implement option-types directly, however it provides discriminated types which can be used to parameterize a record. To implement a Option type, a Boolean type is used as the discriminant; the following example provides a generic to create an option type from any non-limited constrained type: generic
-- Any constrained & non-limited type.
type Element_Type is private;
package Optional_Type is
-- When the discriminant, Has_Element, is true there is an element field,
-- when it is false, there are no fields (hence the null keyword).
type Optional (Has_Element : Boolean) is record
case Has_Element is
when False => Null;
when True => Element : Element_Type;
end case;
end record;
end Optional_Type;
Example usage: package Optional_Integers is new Optional_Type
(Element_Type => Integer);
Foo : Optional_Integers.Optional :=
(Has_Element => True, Element => 5);
Bar : Optional_Integers.Optional :=
(Has_Element => False);
Agda
In Agda, the option type is named ATSIn ATS, the option type is defined as datatype option_t0ype_bool_type (a: t@ype+, bool) =
| Some(a, true) of a
| None(a, false)
stadef option = option_t0ype_bool_type
typedef Option(a: t@ype) = [b:bool] option(a, b)
#include "share/atspre_staload.hats"
fn show_value (opt: Option int): string =
case+ opt of
| None() => "No value"
| Some(s) => tostring_int s
implement main0 (): void = let
val full = Some 42
and empty = None
in
println!("show_value full → ", show_value full);
println!("show_value empty → ", show_value empty);
end
show_value full → 42
show_value empty → No value
C++Since C++17, the option type is defined in the standard library as import std;
using std::nullopt;
using std::optional;
constexpr optional<double> divide(double x, double y) noexcept {
if (y != 0.0) {
return x / y;
}
return nullopt;
}
void readDivisionResults(int x, int y) {
optional<double> result = divide(x, y);
if (result) {
std::println("The quotient of x: {} and y: {} is {}.", x, y, result.value());
} else {
std::println("The quotient of x: {} and y: {} is undefined!");
}
}
int main(int argc, char* argv[]) {
readDivisionResults(1, 5);
readDivisionResults(8, 0);
}
Elm
In Elm, the option type is defined as F#In F#, the option type is defined as 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
HaskellIn Haskell, the option type is defined as 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
IdrisIn Idris, the option type is defined as 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
JavaIn Java, the option type is defined the standard library by the import java.util.Optional;
public class OptionExample {
static String showValue(Optional<Integer> opt) {
return opt.map(x -> String.format("The value is: %d", x)).orElse("No value");
}
public static void main(String[] args) {
Optional<Integer> full = Optional.of(42);
Optional<Integer> empty = Optional.empty();
System.out.printf("showValue(full): %s\n", showValue(full));
System.out.printf("showValue(empty): %s\n", showValue(empty));
}
}
showValue full -> The value is: 42
showValue empty -> No value
Nim
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
OCamlIn OCaml, the option type is defined as 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
Rocq
In Rocq, the option type is defined as RustIn Rust, the option type is defined as fn show_value(opt: Option<i32>) -> String {
opt.map_or("No value".to_owned(), |x: i32| format!("The value is: {}", x))
}
fn main() {
let full: Option<i32> = Some(42);
let empty: Option<i32> = 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
ScalaIn Scala, the option type is defined as 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
In Standard ML, the option type is defined as SwiftIn Swift, the option type is defined as 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
ZigIn Zig, add ? before the type name like Payload n can be captured in an if or while statement, such as const std = @import("std");
fn showValue(allocator: std.mem.Allocator, opt: ?i32) ![]u8 {
return if (opt) |n|
std.fmt.allocPrint(allocator, "The value is: {}", .{n})
else
allocator.dupe(u8, "No value");
}
pub fn main() !void {
// Set up an allocator, and warn if we forget to free any memory.
var gpa: std.heap.DebugAllocator(.{}) = .init;
defer std.debug.assert(gpa.deinit() == .ok);
const allocator = gpa.allocator();
// Prepare the standard output stream.
var buffer: [1024]u8 = undefined;
var writer = std.fs.File.stdout().writer(&buffer);
const stdout = &writer.interface;
// Perform our example.
const full = 42;
const empty = null;
const full_msg = try showValue(allocator, full);
defer allocator.free(full_msg);
try stdout.print("showValue(allocator, full) -> {s}\n", .{full_msg});
const empty_msg = try showValue(allocator, empty);
defer allocator.free(empty_msg);
try stdout.print("showValue(allocator, empty) -> {s}\n", .{empty_msg});
try stdout.flush();
}
showValue(allocator, full) -> The value is: 42
showValue(allocator, empty) -> No value
See alsoReferences
|