Error Handling
A common way of handling failure that we’ve already seen is raising exceptions with failwith
.
For example:
let rec find (l : 'a list) (pred : 'a -> bool) : 'a =
match l with
| [] -> failwith "Not found"
| x::xs -> if pred x then x else find xs pred;;
(find [1;2;3] (fun n -> n > 4);; (* raises an error *)
(find [1;2;3] (fun n -> n > 2);; (* returns 3 *)
This works well when an operation is truly nonsensical. However, it forces programs to use a different class of features— exceptions and exception handlers—to handle failing behaviors. Sometimes, the failure of an operation is a reasonable outcome, and having a way to report a failure, or the absence of an answer, with a normal value rather than an exception is quite useful.
Use option
It would be convenient if we had a value that represented that there is no appropriate value to return in the empty case. Similarly, it would be useful to have the counterpart, a representation of being able to provide some appropriate value. OCaml provides just such a datatype, called option
, which is built-in. If we wrote the definition ourselves, it would look like:
type 'a option =
| None
| Some of 'a
That is, an option
is either None
, which we can use to indicate failure or the lack of an appropriate value, or Some
, which contains a single field that is a value of the option’s type.
Revisiting the find
example with option
let rec find_opt (l : 'a list) (pred : 'a -> bool) : 'a option =
match l with
| [] -> None
| x::xs -> if pred x then Some(x) else find_opt xs pred;;
(find_opt [1;2;3] (fun n -> n > 4);; (* returns None *)
(find_opt [1;2;3] (fun n -> n > 2);; (* returns Some(3) *)
Now a program that calls find, rather than using an exception handler to manage the not found case, can simply match on the option that is returned to decide what to do.
Conclusion
Note that options
aren’t always better than exceptions, as sometimes it’s difficult for the caller to know what to do when None
is returned. But in many cases, when “failure” is something that the caller can reasonably react to, returning an option
is a much more natural choice.