You are currently looking at the < v8.2.0 docs (Reason v3.6 syntax edition). You can find the latest API docs here.
(These docs cover all versions between v3 to v8 and are equivalent to the old BuckleScript docs before the rebrand)
Result
Result types are really useful to describe the result of a certain operation
without relying on exceptions or option
types.
This module gives you useful utilities to create and combine Result
data.
t
type t('a, 'b) =
| Ok('a)
| Error('b);
The type Result.t(result, err)
describes a variant of two states:
Ok(someResult)
represents a successful operation, whereby
`Error(someError)
signals an erronous operation.
In this concrete example, we are defining our own Result
type to reflect an HTTP like
query operation:
REtype responseError = NotAvailable | NotFound;
type queryResult = Belt.Result.t(string, responseError);
let failQueryUser = (username: string): queryResult => {
Error(NotAvailable)
};
getExn
let getExn: t('a, 'b) => 'a;
getExn(res)
: when res
is Ok(n)
, returns n
when res
is Error(m)
, raise an exception
REBelt.Result.getExn(Belt.Result.Ok(42)) == 42;
Belt.Result.getExn(Belt.Result.Error("Invalid data")); /* raises exception */
mapWithDefaultU
let mapWithDefaultU: (t('a, 'c), 'b, (.'a => 'b)) => 'b;
mapWithDefault
let mapWithDefault: (t('a, 'c), 'b, 'a => 'b) => 'b;
mapWithDefault(res, default, f);
: When res is Ok(n)
, returns f(n)
,
otherwise default
.
RElet ok = Belt.Result.Ok(42)
Belt.Result.mapWithDefault(ok, 0, (x) => x / 2) == 21;
let error = Belt.Result.Error("Invalid data")
Belt.Result.mapWithDefault(error, 0, (x) => x / 2) == 0;
mapU
let mapU: (t('a, 'c), [@bs] ('a => 'b)) => t('b, 'c);
map
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.
RElet f = (x) => sqrt(float_of_int(x));
Belt.Result.map(Ok(64), f) == Ok(8.0);
Belt.Result.map(Error("Invalid data"), f) == Error("Invalid data");
flatMapU
let flatMapU: (t('a, 'c), [@bs] ('a => t('b, 'c))) => t('b, 'c);
flatMap
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
.
RElet recip = (x) =>
if (x !== 0.0) {
Belt.Result.Ok(1.0 /. x);
} else {
Belt.Result.Error("Divide by zero");
};
Belt.Result.flatMap(Ok(2.0), recip) == Ok(0.5);
Belt.Result.flatMap(Ok(0.0), recip) == Error("Divide by zero");
Belt.Result.flatMap(Error("Already bad"), recip) == Error("Already bad");
getWithDefault
let getWithDefault: (t('a, 'b), 'a) => 'a;
getWithDefault(res, defaultValue)
: If res
is Ok(n)
, returns n
,
otherwise default
REBelt.Result.getWithDefault(Ok(42), 0) == 42;
Belt.Result.getWithDefault(Error("Invalid Data"), 0) == 0;
isOk
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.
isError
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.
eqU
let eqU: (t('a, 'c), t('b, 'd), (.'a, 'b) => bool) => bool;
eq
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
RElet good1 = Belt.Result.Ok(42);
let good2 = Belt.Result.Ok(32);
let bad1 = Belt.Result.Error("invalid");
let bad2 = Belt.Result.Error("really invalid");
let mod10equal = (a, b) => a mod 10 === b mod 10;
Belt.Result.eq(good1, good2, mod10equal) == true;
Belt.Result.eq(good1, bad1, mod10equal) == false;
Belt.Result.eq(bad2, good2, mod10equal) == false;
Belt.Result.eq(bad1, bad2, mod10equal) == true;
cmpU
let cmpU: (t('a, 'c), t('b, 'd), (.'a, 'b) => int) => int;
cmp
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)
RElet good1 = Belt.Result.Ok(59);
let good2 = Belt.Result.Ok(37);
let bad1 = Belt.Result.Error("invalid");
let bad2 = Belt.Result.Error("really invalid");
let mod10cmp = (a, b) => Pervasives.compare(a mod 10, b mod 10);
Belt.Result.cmp(Ok(39), Ok(57), mod10cmp) == 1;
Belt.Result.cmp(Ok(57), Ok(39), mod10cmp) == (-1);
Belt.Result.cmp(Ok(39), Error("y"), mod10cmp) == 1;
Belt.Result.cmp(Error("x"), Ok(57), mod10cmp) == (-1);
Belt.Result.cmp(Error("x"), Error("y"), mod10cmp) == 0;