Skip to content
Option and Result Combinators
step 1/4

Reading — step 1 of 4

Learn

~1 min readMutable State and Combinators

OCaml's standard library has built-in helpers for option and result that avoid manual pattern matching.

Option module:

Option.is_some (Some 5)            (* true *)
Option.is_none None                 (* true *)

Option.value None ~default:0        (* 0 *)
Option.value (Some 5) ~default:0    (* 5 *)

Option.map (fun x -> x * 2) (Some 5)   (* Some 10 *)
Option.bind (Some 5) (fun x -> Some (x * 2))   (* Some 10 *)

Option.iter (Printf.printf "got %d\n") (Some 42)

Pipe-friendly usage:

let doubled =
    "42"
    |> int_of_string_opt              (* Some 42 *)
    |> Option.map (fun n -> n * 2)    (* Some 84 *)
    |> Option.value ~default:0

Result module for typed errors:

type result = (int, string) Result.t   (* Ok of int | Error of string *)

Result.ok (Ok 5)              (* Some 5 *)
Result.error (Error "bad")    (* Some "bad" *)

Result.map (fun x -> x * 2) (Ok 5)              (* Ok 10 *)
Result.map_error (fun e -> "err: " ^ e) result
Result.bind result (fun x -> if x > 0 then Ok x else Error "neg")

Pattern: validation chain:

let validate_age s =
    match int_of_string_opt s with
    | None -> Error "not a number"
    | Some n when n < 0 -> Error "negative"
    | Some n -> Ok n

let () =
    match validate_age "25" with
    | Ok n -> Printf.printf "age: %d\n" n
    | Error msg -> Printf.printf "error: %s\n" msg

int_of_string_opt and float_of_string_opt return Option instead of throwing — much safer than the throwing versions.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…