package reason-standard

  1. Overview
  2. Docs

Functions for working with computations which may fail.

type ('ok, 'error) t = ('ok, 'error) Result.t

Create

val ok : 'ok -> ('ok, 'error) t

A function alternative to the Ok constructor which can be used in places where the constructor isn't permitted such as at the of a Fun.(|>) or functions like List.map.

Examples

String.reverse "desserts" |> Result.ok = Ok "stressed"
List.map [1; 2; 3] ~f:Result.ok = [Ok 1; Ok 2; Ok 3]
val error : 'error -> ('ok, 'error) t

A function alternative to the Error constructor which can be used in places where the constructor isn't permitted such as at the of a Fun.pipe or functions like List.map.

Note

When targetting the Bucklescript compiler you can use constructors with the fast pipe.

5 |. Ok = (Ok 5)

See the Reason docs for more.

Examples

Int.negate 3 |> Result.error 3 = Error (-3)
List.map [1; 2; 3] ~f:Result.error = [Error 1; Error 2; Error 3]
val attempt : (unit -> 'ok) -> ('ok, exn) t

Run the provided function and wrap the returned value in a Result, catching any exceptions raised.

Examples

Result.attempt (fun () -> 5 / 0) = Error Division_by_zero
let numbers = [|1; 2; 3|] in
Result.attempt (fun () -> numbers.(3)) = 
  Error (Invalid_argument "index out of bounds")
val ofOption : 'ok option -> error:'error -> ('ok, 'error) t

Convert an Option to a Result where a (Some value) becomes (Ok value) and a None becomes (Error error).

Examples

Result.ofOption (Some 84) ~error:"Greater than 100" = Ok 8
Result.ofOption None ~error:"Greater than 100" = 
  Error "Greater than 100"
val isOk : (_, _) t -> bool

Check if a Result is an Ok.

Useful when you want to perform some side affect based on the presence of an Ok like logging.

Note if you need access to the contained value rather than doing Result.isOk followed by Result.getUnsafe its safer and just as convenient to use pattern matching directly or use one of Result.flatMap or Result.map

Examples

Result.isOk (Ok 3) = true
Result.isOk (Error 3) = false
val isError : (_, _) t -> bool

Check if a Result is an Error.

Useful when you want to perform some side affect based on the presence of an Error like logging.

Note if you need access to the contained value rather than doing Result.isOk followed by Result.getUnsafe its safer and just as convenient to use pattern matching directly or use one of Result.flatMap or Result.map

Examples

Result.isError (Ok 3) = false
Result.isError (Error 3) = true
val and_ : ('ok, 'error) t -> ('ok, 'error) t -> ('ok, 'error) t

Returns the first argument if it isError, otherwise return the second argument.

Unlike the Bool.(&&) operator, the and_ function does not short-circuit. When you call and_, both arguments are evaluated before being passed to the function.

Examples

Result.and_ (Ok "Antelope") (Ok "Salmon") = Ok "Salmon"
Result.and_ 
  (Error (`UnexpectedBird "Finch")) 
  (Ok "Salmon") 
  = Error (`UnexpectedBird "Finch")
Result.and_ 
  (Ok "Antelope") 
  (Error (`UnexpectedBird "Finch")) 
    = Error (`UnexpectedBird "Finch")
Result.and_ 
  (Error (`UnexpectedInvertabrate "Honey bee")) 
  (Error (`UnexpectedBird "Finch")) 
    = Error (`UnexpectedBird "Honey Bee")
val or_ : ('ok, 'error) t -> ('ok, 'error) t -> ('ok, 'error) t

Return the first argument if it isOk, otherwise return the second.

Unlike the built in || operator, the or_ function does not short-circuit. When you call or_, both arguments are evaluated before being passed to the function.

Examples

Result.or_ (Ok "Boar") (Ok "Gecko") = (Ok "Boar")
Result.or_ (Error (`UnexpectedInvertabrate "Periwinkle")) (Ok "Gecko") = (Ok "Gecko")
Result.or_ (Ok "Boar") (Error (`UnexpectedInvertabrate "Periwinkle")) = (Ok "Boar") 
Result.or_ (Error (`UnexpectedInvertabrate "Periwinkle")) (Error (`UnexpectedBird "Robin")) = (Error (`UnexpectedBird "Robin"))
val both : ('a, 'error) t -> ('b, 'error) t -> ('a * 'b, 'error) t

Combine two results, if both are Ok returns an Ok containing a Tuple of the values.

If either is an Error, returns the Error.

The same as writing Result.map2 ~f:Tuple.make

Examples

Result.both (Ok "Badger") (Ok "Rhino") = Ok ("Dog", "Rhino")
Result.both (Error (`UnexpectedBird "Flamingo")) (Ok "Rhino") = 
  (Error (`UnexpectedBird "Flamingo"))
Result.both 
  (Ok "Badger") 
  (Error (`UnexpectedInvertabrate "Blue ringed octopus")) = 
    (Error (`UnexpectedInvertabrate "Blue ringed octopus"))
Result.both 
  (Error (`UnexpectedBird "Flamingo")) 
  (Error (`UnexpectedInvertabrate "Blue ringed octopus")) = 
    (Error (`UnexpectedBird "Flamingo"))
val flatten : (('ok, 'error) t, 'error) t -> ('ok, 'error) t

Collapse a nested result, removing one layer of nesting.

Examples

Result.flatten (Ok (Ok 2)) = Ok 2
Result.flatten (Ok (Error (`UnexpectedBird "Peregrin falcon"))) = 
  (Error (`UnexpectedBird "Peregrin falcon"))
Result.flatten (Error (`UnexpectedInvertabrate "Woodlouse")) = 
  (Error (`UnexpectedInvertabrate "Woodlouse"))
val get : ('ok, 'error) t -> default:'ok -> 'ok

Unwrap a Result using the ~default value in case of an Error

Examples

Result.get ~default:0 (Ok 12) = 12
Result.get ~default:0 ((Error (`UnexpectedBird "Ostrich"))) = 0
val (|?) : ('a, 'error) t -> 'a -> 'a

An operator version of Result.get where the default value goes to the right of the operator.

Examples

The following eamples assume open Result.Infix is in scope.

Result.(Ok 4 |? 8) = 4
Result.(Error "Missing number!" |? 8) = 8
val getUnsafe : ('ok, _) t -> 'ok

Unwrap a Result, raising an exception in case of an Error

Exceptions

Raises an Invalid_argument "Result.getUnsafe called with an Error" exception.

Examples

Result.getUnsafe (Ok 12) = 12
Result.getUnsafe (Error "bad") 
val getError : ('ok, 'error) t -> default:'error -> 'error

Like Result.get but unwraps an Error value instead

Examples

Result.getError
  (Error (`UnexpectedBird "Swallow")) 
  ~default:(`UnexpectedInvertabrate "Ladybird") = 
    `UnexpectedBird "Swallow"
Result.getError 
  (Ok 5) 
  ~default:(`UnexpectedInvertabrate "Ladybird") = 
    `UnexpectedInvertabrate "Ladybird"
val map2 : ('a, 'error) t -> ('b, 'error) t -> f:('a -> 'b -> 'c) -> ('c, 'error) t

Combine two results

If one of the results is an Error, that becomes the return result.

If both are Error values, returns its first.

Examples

Result.map2 (Ok 7) (Ok 3) ~f:Int.add = Ok 10
Result.map2 (Error "A") (Ok 3) ~f:Int.add = Error "A"
Result.map2 (Ok 7) (Error "B") ~f:Int.add = Error "B"
Result.map2 (Error "A") (Error "B") ~f:Int.add = Error "A"
val values : ('ok, 'error) t list -> ('ok list, 'error) t

If all of the elements of a list are Ok, returns an Ok of the the list of unwrapped values.

If any of the elements are an Error, the first one encountered is returned.

Examples

Result.values [Ok 1; Ok 2; Ok 3; Ok 4] = Ok [1; 2; 3; 4]
Result.values [Ok 1; Error "two"; Ok 3; Error "four"] = Error "two"
val map : ('a, 'error) t -> f:('a -> 'b) -> ('b, 'error) t

Transforms the 'ok in a result using f. Leaves the 'error untouched.

Examples

Result.map (Ok 3) ~f:(Int.add 1) = Ok 9
Result.map (Error "three") ~f:(Int.add 1) = Error "three"
val mapError : ('ok, 'a) t -> f:('a -> 'b) -> ('ok, 'b) t

Transforms the value in an Error using f. Leaves an Ok untouched.

Examples

Result.mapError (Ok 3) ~f:String.reverse = Ok 3
Result.mapError (Error "bad") ~f:(Int.add 1)  = Error "bad"
val transpose : ('ok option, 'error) t -> ('ok, 'error) t option

Converts an Result.t('error, Option.t('ok) into a Option.t(Result.t('ok, 'error))

Examples

Result.transpose (Ok (Some 5)) = Some (Ok 5)
Result.transpose (Ok (None)) = None
Result.transpose (Error "fail") = (Some (Error "fail"))
val flatMap : ('a, 'error) t -> f:('a -> ('b, 'error) t) -> ('b, 'error) t

Run a function which may fail on a result.

Short-circuits of called with an Error.

Examples

let reciprical (x:float) : (string, float) Standard.Result.t = (
  if (x = 0.0) then
    Error "Divide by zero"
  else
    Ok (1.0 /. x)
)

let root (x:float) : (string, float) Standard.Result.t = (
  if (x < 0.0) then
    Error "Cannot be negative"
  else
    Ok (Float.squareRoot x)
)

Examples

Result.flatMap ~f:reciprical (Ok 4.0) = Ok 0.25
Result.flatMap ~f:reciprical (Error "Missing number!") = Error "Missing number!"
Result.flatMap ~f:reciprical (Ok 0.0) = Error "Divide by zero"
Result.flatMap (Ok 4.0) ~f:root  |> Result.flatMap ~f:reciprical = Ok 0.5
Result.flatMap (Ok -2.0) ~f:root |> Result.flatMap ~f:reciprical = Error "Cannot be negative"
Result.flatMap (Ok 0.0) ~f:root |> Result.flatMap ~f:reciprical = Error "Divide by zero"
val forEach : ('ok, _) t -> f:('ok -> unit) -> unit

Run a function against an (Ok value), ignores Errors.

Examples

Result.forEach (Ok "Dog") ~f:print_endline
(* prints "Dog" *)

Convert

val toOption : ('ok, _) t -> 'ok option

Convert a Result to an Option.

An Ok x becomes Some x

An Error _ becomes None

Examples

Result.toOption (Ok 42) = Some 42
Result.toOption (Error "Missing number!") = None

Compare

val equal : ('ok -> 'ok -> bool) -> ('error -> 'error -> bool) -> ('ok, 'error) t -> ('ok, 'error) t -> bool

Test two results for equality using the provided functions.

Examples

Result.equal String.equal Int.equal (Ok 3) (Ok 3) = true
Result.equal String.equal Int.equal (Ok 3) (Ok 4) = false
Result.equal String.equal Int.equal (Error "Fail") (Error "Fail") = true
Result.equal String.equal Int.equal (Error "Expected error") (Error "Unexpected error") = false
Result.equal String.equal Int.equal (Error "Fail") (Ok 4) = false
val compare : ('ok -> 'ok -> int) -> ('error -> 'error -> int) -> ('ok, 'error) t -> ('ok, 'error) t -> int

Compare results for using the provided functions.

In the case when one of the results is an Error and one is Ok, Errors are considered 'less' then Oks

Examples

Result.compare String.compare Int.compare (Ok 3) (Ok 3) = 0
Result.compare String.compare Int.compare (Ok 3) (Ok 4) = -1
Result.compare String.compare Int.compare (Error "Fail") (Error "Fail") = 0
Result.compare String.compare Int.compare (Error "Fail") (Ok 4) = -1
Result.compare String.compare Int.compare (Ok 4) (Error "Fail") = 1
Result.compare String.compare Int.compare (Error "Expected error") (Error "Unexpected error") = -1
module Infix : sig ... end

In functions that make heavy use of Results placing an

val let+ : ('a, 'error) t -> ('a -> 'b) -> ('b, 'error) t

The binding operator for Core.Result.map

Note Currently this is only supported by the OCaml syntax.

Note This requires at least OCaml 4.08 which means currently this is only supported by the native compiler.

val and+ : ('a, 'error) t -> ('b, 'error) t -> ('a * 'b, 'error) t

The binding operator for Core.Result.both

Note Currently this is only supported by the OCaml syntax.

Note This requires at least OCaml 4.08 which means currently this is only supported by the native compiler.

val let* : ('a, 'error) t -> ('a -> ('b, 'error) t) -> ('b, 'error) t

The binding operator for Core.Result.flatMap

Note Currently this is only supported by the OCaml syntax.

Note This requires at least OCaml 4.08 which means currently this is only supported by the native compiler.

val and* : ('a, 'error) t -> ('b, 'error) t -> ('a * 'b, 'error) t

The binding operator for Core.Result.both

Note Currently this is only supported by the OCaml syntax.

Note This requires at least OCaml 4.08 which means currently this is only supported by the native compiler.