![]() | 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?
).
![]() | 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 maybeNothing>>=f=Nothing-- Fails if the previous monad fails(Justx)>>=f=fx-- Succeeds when both monads succeed
The monadic nature of the option type is useful for efficiently tracking failure and errors. [3]
Ada 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.typeElement_Typeisprivate;packageOptional_Typeis-- When the discriminant, Has_Element, is true there is an element field,-- when it is false, there are no fields (hence the null keyword).typeOptional(Has_Element: Boolean)isrecordcaseHas_ElementiswhenFalse=>Null;whenTrue=>Element:Element_Type;endcase;end record;endOptional_Type;
Example usage:
packageOptional_Integersis newOptional_Type(Element_Type=> Integer);Foo:Optional_Integers.Optional:=(Has_Element=>True,Element=>5);Bar:Optional_Integers.Optional:=(Has_Element=>False);
![]() | This section needs expansionwith: example usage. You can help by adding to it. (July 2022) |
In Agda, the option type is named Maybe
with variants nothing
and justa
.
In ATS, the option type is defined as
datatypeoption_t0ype_bool_type(a:t@ype+,bool)=|Some(a,true)ofa|None(a,false)stadefoption=option_t0ype_bool_typetypedefOption(a:t@ype)=[b:bool]option(a,b)
#include"share/atspre_staload.hats"fnshow_value(opt:Optionint):string=case+optof|None()=>"No value"|Some(s)=>tostring_intsimplementmain0():void=letvalfull=Some42andempty=Noneinprintln!("show_value full → ",show_valuefull);println!("show_value empty → ",show_valueempty);end
show_value full → 42show_value empty → No value
Since C++17, the option type is defined in the standard library as template<typenameT>std::optional<T>
.
std::optional<double>divide(intx,inty){if(y!=0.0)returnx/y;return{};}
![]() | This section needs expansionwith: example usage. You can help by adding to it. (July 2022) |
In Coq, the option type is defined as Inductiveoption(A:Type):Type:=|Some:A->optionA|None:optionA.
.
![]() | This section needs expansionwith: example usage. You can help by adding to it. (July 2022) |
In Elm, the option type is defined as typeMaybea=Justa|Nothing
. [4]
In F#, the option type is defined as type'aoption=None|Someof'a
. [5]
letshowValue=Option.fold(fun_x->sprintf"The value is: %d"x)"No value"letfull=Some42letempty=NoneshowValuefull|>printfn"showValue full -> %s"showValueempty|>printfn"showValue empty -> %s"
showValue full -> The value is: 42showValue empty -> No value
In Haskell, the option type is defined as dataMaybea=Nothing|Justa
. [6]
showValue::MaybeInt->StringshowValue=foldl(\_x->"The value is: "++showx)"No value"main::IO()main=doletfull=Just42letempty=NothingputStrLn$"showValue full -> "++showValuefullputStrLn$"showValue empty -> "++showValueempty
showValue full -> The value is: 42showValue empty -> No value
In Idris, the option type is defined as dataMaybea=Nothing|Justa
.
showValue:MaybeInt->String showValue=foldl(\_,x=>"The value is "++showx)"No value"main:IO() main=doletfull=Just42letempty=NothingputStrLn$"showValue full -> "++showValuefull putStrLn$"showValue empty -> "++showValueempty
showValue full -> The value is: 42showValue empty -> No value
In Java, the option type is defined the standard library by the java.util.Optional<T>
class.
importjava.util.Optional;classOption{staticStringshowValue(Optional<Integer>opt){returnopt.map(x->String.format("The value is: %d",x)).orElse("No value");}publicstaticvoidmain(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: 42showValue empty -> No value
![]() | This section needs expansionwith: the definition. You can help by adding to it. (July 2022) |
importstd/optionsprocshowValue(opt:Option[int]):string=opt.map(proc(x:int):string="The value is: "&$x).get("No value")letfull=some(42)empty=none(int)echo"showValue(full) -> ",showValue(full)echo"showValue(empty) -> ",showValue(empty)
showValue(full) -> The Value is: 42showValue(empty) -> No value
In OCaml, the option type is defined as type'aoption=None|Someof'a
. [7]
letshow_value=Option.fold~none:"No value"~some:(funx->"The value is: "^string_of_intx)let()=letfull=Some42inletempty=Noneinprint_endline("show_value full -> "^show_valuefull);print_endline("show_value empty -> "^show_valueempty)
show_value full -> The value is: 42show_value empty -> No value
In Rust, the option type is defined as enumOption<T>{None,Some(T)}
. [8]
fnshow_value(opt: Option<i32>)-> String{opt.map_or("No value".to_owned(),|x|format!("The value is: {}",x))}fnmain(){letfull=Some(42);letempty=None;println!("show_value(full) -> {}",show_value(full));println!("show_value(empty) -> {}",show_value(empty));}
show_value(full) -> The value is: 42show_value(empty) -> No value
In Scala, the option type is defined as sealedabstractclassOption[+A]
, a type extended by finalcaseclassSome[+A](value:A)
and caseobjectNone
.
objectMain:defshowValue(opt:Option[Int]):String=opt.fold("No value")(x=>s"The value is: $x")defmain(args:Array[String]):Unit=valfull=Some(42)valempty=Noneprintln(s"showValue(full) -> ${showValue(full)}")println(s"showValue(empty) -> ${showValue(empty)}")
showValue(full) -> The value is: 42showValue(empty) -> No value
![]() | This section needs expansionwith: example usage. You can help by adding to it. (July 2022) |
In Standard ML, the option type is defined as datatype'aoption=NONE|SOMEof'a
.
In Swift, the option type is defined as enumOptional<T>{casenone,some(T)}
but is generally written as T?
. [9]
funcshowValue(_opt:Int?)->String{returnopt.map{"The value is: \($0)"}??"No value"}letfull=42letempty:Int?=nilprint("showValue(full) -> \(showValue(full))")print("showValue(empty) -> \(showValue(empty))")
showValue(full) -> The value is: 42showValue(empty) -> No value
In Zig, add ? before the type name like ?i32
to make it an 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
.
conststd=@import("std");fnshowValue(allocator:std.mem.Allocator,opt:?i32)![]u8{returnif(opt)|n|std.fmt.allocPrint(allocator,"The value is: {}",.{n})elseallocator.dupe(u8,"No value");}pubfnmain()!void{// Set up an allocator, and warn if we forget to free any memory.vargpa:std.heap.DebugAllocator(.{})=.init;deferstd.debug.assert(gpa.deinit()==.ok);constallocator=gpa.allocator();// Prepare the standard output stream.conststdout=std.io.getStdOut().writer();// Perform our example.constfull=42;constempty=null;constfull_msg=tryshowValue(allocator,full);deferallocator.free(full_msg);trystdout.print("showValue(allocator, full) -> {s}\n",.{full_msg});constempty_msg=tryshowValue(allocator,empty);deferallocator.free(empty_msg);trystdout.print("showValue(allocator, empty) -> {s}\n",.{empty_msg});}
showValue(allocator, full) -> The value is: 42 showValue(allocator, empty) -> No value