Search code examples
functional-programmingmatchocamlalgebraic-data-typesoption-type

What is Some in OCaml


This Ocaml code traverses a list and outputs the last element.

I dont understand the second condition where we output Some x

let rec last = function 
| [] -> None 
| x::[] -> Some x
| _ :: t -> last t ;;
  • So if the list is empty we return null.
  • If x is the last element we return Some x (* what is Some x in this context? *)
  • If x is not the last element we go further in the list.

Solution

  • Some is a constructor for the option type. None is the other constructor. Consider the following definition of option.

    type 'a option = None | Some of 'a
    

    The net effect of this is to provide for functions to have an option to return a value, or a value representing nothing. Imagine I want to search for the index of an item in a list. What should I return if the value isn't in the list?

    let find_index value lst = 
      let rec aux value lst idx =
        match lst with
        | [] -> None
        | x::_ when x = value -> Some idx 
        | _::xs -> aux value xs (idx + 1)
      in
      aux value lst 0
    
    # find_index 4 [1; 8; 2; 5; 4; 10];;
    - : int option = Some 4
    # find_index 4 [1; 8; 2; 5; 7; 10];;
    - : int option = None
    

    Both values have type int option so OCaml's type system is happy.

    In your example, an empty list doesn't have a last element, so you return None.

    We can then pattern match on this to handle the two situations:

    let some_list = [2; 3; 4]
    
    let () =
      match last some_list with
      | None -> print_endline "This list doesn't have a last item."
      | Some item -> print_endline ("The last item found was " ^ string_of_int item)
    

    You may have run into languages where this type of situations is handled by returning a special error value. We could return -1 for instance. Or we could throw a ValueNotFound exception.