Skip to content

Module Belt.Result

Belt.Result

Utilities for result data type.

Belt.Result is a data type with two variants: Ok and Error. Each of these variants can contain data, and those two pieces of data need not have the same data type. Belt.Result is useful when you need to not only determine whether some data is valid or not (use Belt.Option for that), but also keep information about the invalid data.

In the examples, we presume the existence of two variables:

ocaml
let good = Ok 42
let bad = Error "Invalid data"
reasonml
let good = Ok(42);
let bad = Error("Invalid data");
ocaml
type ('a, 'b) t = ('a, 'b) result =
reasonml
type t('a, 'b) = result('a, 'b) =
ocaml
| Ok of 'a
reasonml
| Ok('a)
ocaml
| Error of 'b
reasonml
| Error('b)
ocaml
reasonml
;
ocaml
val getExn : ('a, 'b) t -> 'a
reasonml
let getExn: t('a, 'b) => 'a;

getExn res

when res is Ok n, returns n when res is Error m, raise an exception

ocaml
  getExn good = 42;;
  getExn bad;; (* raises exception *)
reasonml
getExn(good) == 42;
getExn(bad); /* raises exception */
ocaml
val mapWithDefaultU : ('a, 'c) t -> 'b -> ('a -> 'b) Js.Fn.arity1 -> 'b
reasonml
let mapWithDefaultU: t('a, 'c) => 'b => Js.Fn.arity1(('a => 'b)) => 'b;
ocaml
val mapWithDefault : ('a, 'c) t -> 'b -> ('a -> 'b) -> 'b
reasonml
let mapWithDefault: t('a, 'c) => 'b => ('a => 'b) => 'b;

mapWithDefault res default f

When res is Ok n, returns f n, otherwise default.

ocaml
  mapWithDefault good 0 (fun x -> x / 2) = 21
  mapWithDefault bad 0 (fun x -> x / 2) = 0
reasonml
mapWithDefault(good, 0, x => x / 2) == 21(mapWithDefault, bad, 0, x => x / 2)
== 0;
ocaml
val mapU : ('a, 'c) t -> ('a -> 'b) Js.Fn.arity1 -> ('b, 'c) t
reasonml
let mapU: t('a, 'c) => Js.Fn.arity1(('a => 'b)) => t('b, 'c);
ocaml
val map : ('a, 'c) t -> ('a -> 'b) -> ('b, 'c) t
reasonml
let map: t('a, 'c) => ('a => 'b) => t('b, 'c);

map res f

When res is Ok n, returns Ok (f n). Otherwise returns res unchanged. Function f takes a value of the same type as n and returns an ordinary value.

ocaml
  let f x = sqrt (float_of_int x)
  map (Ok 64) f = Ok 8.0
  map (Error "Invalid data") f = Error "Invalid data"
ocaml
val flatMapU : ('a, 'c) t -> ('a -> ('b, 'c) t) Js.Fn.arity1 -> ('b, 'c) t
reasonml
let flatMapU: t('a, 'c) => Js.Fn.arity1(('a => t('b, 'c))) => t('b, 'c);
ocaml
val flatMap : ('a, 'c) t -> ('a -> ('b, 'c) t) -> ('b, 'c) t
reasonml
let flatMap: t('a, 'c) => ('a => t('b, 'c)) => t('b, 'c);

flatMap res f

When res is Ok n, returns f n. Otherwise, returns res unchanged. Function f takes a value of the same type as n and returns a Belt.Result.

ocaml
let recip x =
  if x != 0.0
  then
    Ok (1.0 /. x)
  else
    Error "Divide by zero"

    flatMap (Ok 2.0) recip = Ok 0.5
    flatMap (Ok 0.0) recip = Error "Divide by zero"
    flatMap (Error "Already bad") recip = Error "Already bad"
ocaml
val getWithDefault : ('a, 'b) t -> 'a -> 'a
reasonml
let getWithDefault: t('a, 'b) => 'a => 'a;

getWithDefault res defaultValue

if res is Ok n, returns n, otherwise default

ocaml
  getWithDefault (Ok 42) 0 = 42
  getWithDefault (Error "Invalid Data") = 0
reasonml
getWithDefault(Ok(42), 0) == 42(getWithDefault, Error("Invalid Data")) == 0;
ocaml
val isOk : ('a, 'b) t -> bool
reasonml
let isOk: t('a, 'b) => bool;

isOk res

Returns true if res is of the form Ok n, false if it is the Error e variant.

ocaml
val isError : ('a, 'b) t -> bool
reasonml
let isError: t('a, 'b) => bool;

isError res

Returns true if res is of the form Error e, false if it is the Ok n variant.

ocaml
val eqU : ('a, 'c) t -> ('b, 'd) t -> ('a -> 'b -> bool) Js.Fn.arity2 -> bool
reasonml
let eqU: t('a, 'c) => t('b, 'd) => Js.Fn.arity2(('a => 'b => bool)) => bool;
ocaml
val eq : ('a, 'c) t -> ('b, 'd) t -> ('a -> 'b -> bool) -> bool
reasonml
let eq: t('a, 'c) => t('b, 'd) => ('a => 'b => bool) => bool;

eq res1 res2 f

Determine if two Belt.Result variables are equal with respect to an equality function. If res1 and res2 are of the form Ok n and Ok m, return the result of f n m. If one of res1 and res2 are of the form Error e, return false If both res1 and res2 are of the form Error e, return true

ocaml
  let good1 = Ok 42
  let good2 = Ok 32
  let bad1 = Error "invalid"
  let bad2 = Error "really invalid"

  let mod10equal a b =
    a mod 10 == b mod 10

  eq good1 good2 mod10equal = true
  eq good1 bad1 mod10equal = false
  eq bad2 good2 mod10equal = false
  eq bad1 bad2 mod10equal = true
ocaml
val cmpU : ('a, 'c) t -> ('b, 'd) t -> ('a -> 'b -> int) Js.Fn.arity2 -> int
reasonml
let cmpU: t('a, 'c) => t('b, 'd) => Js.Fn.arity2(('a => 'b => int)) => int;
ocaml
val cmp : ('a, 'c) t -> ('b, 'd) t -> ('a -> 'b -> int) -> int
reasonml
let cmp: t('a, 'c) => t('b, 'd) => ('a => 'b => int) => int;

cmp res1 res2 f

Compare two Belt.Result variables with respect to a comparison function. The comparison function returns -1 if the first variable is "less than" the second, 0 if the two variables are equal, and 1 if the first is "greater than" the second.

If res1 and res2 are of the form Ok n and Ok m, return the result of f n m. If res1 is of the form Error e and res2 of the form Ok n, return -1 (nothing is less than something) If res1 is of the form Ok n and res2 of the form Error e, return 1 (something is greater than nothing) If both res1 and res2 are of the form Error e, return 0 (equal)

ocaml
  let good1 = Ok 59
  let good2 = Ok 37
  let bad1 = Error "invalid"
  let bad2 = Error "really invalid"

  let mod10cmp a b =
    Pervasives.compare (a mod 10) (b mod 10)

  cmp (Ok 39) (Ok 57) mod10cmp = 1
  cmp (Ok 57) (Ok 39) mod10cmp = -1
  cmp (Ok 39) (Error "y") mod10cmp = 1
  cmp (Error "x") (Ok 57) mod10cmp = -1
  cmp (Error "x") (Error "y") mod10cmp = 0
reasonml
let good1 = Ok(59);
let good2 = Ok(37);
let bad1 = Error("invalid");
let bad2 = Error("really invalid");

let mod10cmp = (a, b) =>
  Pervasives.compare(a mod 10, b mod 10, cmp, Ok(39), Ok(57), mod10cmp)
  == 1(cmp, Ok(57), Ok(39), mod10cmp)
  == - 1(cmp, Ok(39), Error("y"), mod10cmp)
  == 1(cmp, Error("x"), Ok(57), mod10cmp)
  == - 1(cmp, Error("x"), Error("y"), mod10cmp)
  == 0;