There's another built in variant in the OCaml library called options
type 'a option = None | Some of 'a
This means that option can either hold nothing (None), or something of type 'a (Some).
None;;
Some 1;;
- : 'a option = None
- : int option = Some 1
We can also put some more complex data in there:
Some [1; 2; 3];;
- : int list option = Some [1; 2; 3]
How do we get the data out of an option? Pattern matching!
let get_val default = function
| None -> default
| Some x -> x;;
val get_val : 'a -> 'a option -> 'a = <fun>
options are useful for returning something from a function that might return something, or might not.
Let's say we want to get the maximum value in a list. We can define list_max to take the biggest item in a list, and return an int option, where the value would be None if there's nothing in the list:
let rec list_max (lst : 'a list) : 'a option = function
| [] -> None
| h :: t -> Some (max h (list_max t))
File "[4]", lines 1-3, characters 33-34:
1 | .................................: 'a option = function
2 | | [] -> None
3 | | [] -> Some (max h (list_max t))
Error: This expression has type 'a -> 'b
but an expression was expected of type 'c option
What went wrong here? In our call max h (list_max t), we're comparing an 'a to an 'a option, which doesn't exactly work. We need to get the value out of the option first.
let rec list_max = function
| [] -> None
| h :: t -> begin
match list_max t with
(* here we match the result of list_max *)
(* if we got nothing, we need to return the head, because
that's the only element in the list*)
| None -> Some h
(* on the other hand, if we did get something, return the max of
that and the tail *)
| Some m -> Some (max h m)
end
val list_max : 'a list -> 'a option = <fun>
list_max [3; 1; 4; 1; 5; 9; 2; 6];;
list_max [];;
- : int option = Some 9
- : 'a option = None
Here we see two words we've never seen before, begin and end. They just mean ( and ) respectively, and help OCaml determine scope.
Options let us avoid the Billion Dollar Mistake. He invented Quick Sort, and he calls null his "billion dollar mistake." He was designing type system for an OOL, and he included null, which he believes has caused over a billions dollars lost in the past 40 years.