API / Belt / Result

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:

RE
type 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

RE
Belt.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.

RE
let 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.

RE
let 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.

RE
let 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

RE
Belt.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

RE
let 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)

RE
let 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;