API / Belt / Result

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

RES
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:

RES
type responseError = NotAvailable | NotFound type queryResult = 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

RES
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.

RES
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>, (. '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.

RES
let f = (x) => sqrt(Belt.Int.toFloat(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>, (. '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.

RES
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

RES
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

RES
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) => mod(a, 10) === mod(b, 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)

RES
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(mod(a, 10), mod(b, 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