Skip to content
Lesson 4 of 7

Step 1 of 4 · Reading · ~1 min

Learn

Mutable 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. A ('a, 'e) result is Ok of 'a | Error of 'e:

let r : (int, string) result = Ok 5

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

Result.to_option r                            (* Some 5 *)
Result.value r ~default:0                     (* 5 *)

Result.ok and Result.error CONSTRUCT, they do not extract: Result.ok 5 is Ok 5. To go the other way, use Result.to_option or Result.value.

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.

Up nextHigher-Order FunctionsHigher-Order, Exceptions, Imperative

Discussion

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

Sign in to post a comment or reply.

Loading…