Option type

In programming languages (more so 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 (`Maybe (Maybe A)``Maybe A`), while nullable types do not (`String??` = `String?`).

Theoretical aspects

In type theory, it may be written as: ${\displaystyle A^{?}=A+1}$. This expresses the fact that for a given set of values in ${\displaystyle A}$, an option type adds exactly one additional value (the empty value) to the set of valid values for ${\displaystyle A}$. 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.

An option type can also be seen as a collection containing either one or zero elements.

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]

Names and definitions

In different programming languages, the option type has various names and definitions.

• In Agda, it is named `Maybe` with variants `nothing` and `just a`.
• In Coq, it is defined as `Inductive option (A:Type) : Type := | Some : A -> option A | None : option A.`.
• In Haskell, it is named Maybe, and defined as `data Maybe a = Nothing | Just a`.
• In Idris, it is defined as `data Maybe a = Nothing | Just a`.
• In Next Generation Shell, it is named `Box` with sub-types `EmptyBox` and `FullBox`.
• In OCaml, it is defined as `type 'a option = None | Some of 'a`.
• In Rust, it is defined as `enum Option<T> { None, Some(T) }`.
• In Scala, it is defined as parameterized abstract class `'.. Option[A] = if (x == null) None else Some(x)..`.
• In Standard ML, it is defined as `datatype 'a option = NONE | SOME of 'a`.
• In Swift, it is defined as `enum Optional<T> { case none, some(T) }` but is generally written as `T?`.
• In Kotlin, it can be defined as `sealed class Option<out A> { object None : Option<Nothing>(); data class Some<out A>(val a: A) : Option<A>() }`

Examples

Ada does not implement option-types directly, however it provides a more robust method for parameterizing a record known as discriminated types. To implement a Option type, simply use the Boolean type 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;
```

Scala

Scala implements `Option` as a parameterized type, so a variable can be an `Option`, accessed as follows:[4]

```// Defining variables that are Options of type Int
val res1: Option[Int] = Some(42)
val res2: Option[Int] = None

// sample 1 :  This function uses pattern matching to deconstruct Options
def compute(opt: Option[Int]) = opt match {
case None => "No value"
case Some(x) => "The value is: " + x
}

// sample 2 :  This function uses built-in fold method
def compute(opt: Option[Int]) = opt.fold("No Value")(v => "The value is:" + v )

println(compute(res1))  // The value is: 42
println(compute(res2))  // No value
```

Two main ways to use an `Option` value exist. The first, not the best, is the pattern matching, as in the first example. The second, the best practice is a monadic approach, as in the second example. In this way, a program is safe, as it can generate no exception or error (e.g., by trying to obtain the value of an `Option` variable that is equal to `None`). Thus, it essentially works as a type-safe alternative to the null value.

Kotlin

Kotlin emulates option with a Nullable type which is expressed using a question mark:

```fun compute(value: Int?): String {
if(value == null) {
return "No value"
} else {
return "The value is: \$value"
}
}

println(compute(42)) // The value is: 42
println(compute(null)) // No value
```

Java 8

```// Defining variables that are Options of type Int
Optional<Integer> res1 = Optional.of(42);
Optional<Integer> res2 = Optional.empty();

// sample 1 :  This function uses pattern matching to deconstruct Options
String compute(Optional<Integer> opt) {
if(opt.isPresent()) {
return "The value is: " + opt.get();
} else {
return "No value";
}
}

// sample 2 :  This function uses map and alternative
String compute(Optional<Integer> opt) {
return opt.map((v) -> "The value is:" + v).orElse("No Value");
}

System.out.println(compute(res1))  // The value is: 42
System.out.println(compute(res2))  // No value
```

Next Generation Shell

```res1 = Box(42)  # <FullBox val=42>
res2 = Box()    # <EmptyBox>

# Alternative 1 - more idiomatic
F compute(b:EmptyBox) "No value"
F compute(b:FullBox) "The value is: \${b.get()}"

# Alternative 2 - extensive usage of Box, somewhat idiomatic
F compute(b:Box) b.map("The value is: \${X}").get("No value")

# Alternative 3 - more similar to other examples
F compute(b:Box) {
b returns "The value is: \${b.get()}"
"No value"
}

echo(compute(res1))
# Output: The value is: 42
echo(compute(res2))
# Output: No value```

OCaml

OCaml implements `Option` as a parameterized variant type. `Option`s are constructed and deconstructed as follows:

```(* Deconstructing options *)
let compute opt = match opt with
| None -> "No value"
| Some x -> "The value is: " ^ string_of_int x

print_endline (compute None) (* "No value" *)
print_endline (compute (Some 42)) (* "The value is: 42" *)
```

F#

```(* This function uses pattern matching to deconstruct Options *)
let compute = function
| None   -> "No value"
| Some x -> sprintf "The value is: %d" x

printfn "%s" (compute <| Some 42)(* The value is: 42 *)
printfn "%s" (compute None)      (* No value         *)
```

```-- This function uses pattern matching to deconstruct Maybes
compute :: Maybe Int -> String
compute Nothing  = "No value"
compute (Just x) = "The value is: " ++ show x

main :: IO ()
main = do
print \$ compute (Just 42) -- The value is: 42
print \$ compute Nothing -- No value
```

Swift

```func compute(_ x: Int?) -> String {
// This function uses optional binding to deconstruct optionals
if let y = x {
// y is now the non-optional `Int` content of `x`, if it has any
return "The value is: \(y)"
} else {
return "No value"
}
}

print(compute(42)) // The value is: 42
print(compute(nil)) // No value
```
```func compute(_ x: Int?) -> String {
// This function uses `map` to transform the optional if it has a value,
// or pass along the nil if it doesn't. If `map` results in nil,
// the nil coalescing operator `??` sets a fall-back value of "No value"
return x.map { unwrappedX in "The value is: \(unwrappedX)" } ?? "No value"
}

print(compute(42)) // The value is: 42
print(compute(nil)) // No value
```
```func compute(_ x: Int?) -> String {
// This function uses pattern matching to deconstruct optionals
switch x {
case .none:
return "No value"
case .some(let y):
return "The value is: \(y)"
}
}

print(compute(42)) // The value is: 42
print(compute(nil)) // No value
```
```func compute(_ x: Int?) -> String {
// This function asserts that x has a value, forcefully unwraps x
// and CRASHES if nil is encountered!
return "The value is: \(x!)"
}

print(compute(42)) // The value is: 42
print(compute(nil)) // Crash!
```

Rust

```fn main() {
// This function uses pattern matching to deconstruct optionals
fn compute(x: Option<i32>) -> String {
match x {
Some(a) => format!("The value is: {}", a),
None    => format!("No value")
}
}

println!("{}", compute(Some(42))); // The value is: 42
println!("{}", compute(None)); // No value
}
```