Skip to content

Instantly share code, notes, and snippets.

@alex35mil
Created October 28, 2020 09:36
Show Gist options
  • Save alex35mil/99053e44b508ee5250a64ac7d99a7dcd to your computer and use it in GitHub Desktop.
Save alex35mil/99053e44b508ee5250a64ac7d99a7dcd to your computer and use it in GitHub Desktop.

Promise.res

A slightly modified version of standard ReScript's Js.Promise module.

Key differences are:

  • t-first api
  • contains few helpers like Promise.result and Promise.wait (which is what I want most of the time in apps)

Soundness is on the same level as in the original bindings.

If you want more safety, consider reason-promise.

type t<+'a> = Js.Promise.t<'a>
type error = Js.Promise.error
type result<'ok, 'error> = t<Result.t<'ok, 'error>>
@new
external make: ((@uncurry ~resolve: (. 'a) => unit, ~reject: (. exn) => unit) => unit) => t<'a> = "Promise"
@val @scope("Promise") external resolve: 'a => t<'a> = "resolve"
@val @scope("Promise") external reject: exn => t<'a> = "reject"
@val @scope("Promise")
external all: array<t<'a>> => t<array<'a>> = "all"
@val @scope("Promise")
external two: ((t<'a0>, t<'a1>)) => t<('a0, 'a1)> = "all"
@val @scope("Promise")
external three: ((t<'a0>, t<'a1>, t<'a2>)) => t<('a0, 'a1, 'a2)> = "all"
@val @scope("Promise")
external four: ((t<'a0>, t<'a1>, t<'a2>, t<'a3>)) => t<('a0, 'a1, 'a2, 'a3)> = "all"
@val @scope("Promise")
external five: ((t<'a0>, t<'a1>, t<'a2>, t<'a3>, t<'a4>)) => t<('a0, 'a1, 'a2, 'a3, 'a4)> = "all"
@val @scope("Promise")
external six: ((t<'a0>, t<'a1>, t<'a2>, t<'a3>, t<'a4>, t<'a5>)) => t<('a0, 'a1, 'a2, 'a3, 'a4, 'a5)> = "all"
@val @scope("Promise")
external seven: ((t<'a0>, t<'a1>, t<'a2>, t<'a3>, t<'a4>, t<'a5>, t<'a6>)) => t<('a0, 'a1, 'a2, 'a3, 'a4, 'a5, 'a6)> = "all"
@val @scope("Promise")
external race: array<t<'a>> => t<'a> = "race"
@send
external andThen: (t<'a>, @uncurry ('a => t<'b>)) => t<'b> = "then"
@send
external catch: (t<'a>, @uncurry (error => t<'a>)) => t<'a> = "catch"
let map = (x: t<'a>, fn: 'a => 'b): t<'b> => x->andThen(x => x->fn->resolve)
let tap =
(x: t<'a>, fn: 'a => 'b): t<'a> =>
x->andThen(x => {
x->fn
x->resolve
})
let result =
(x: t<'ok>): result<'ok, 'error> =>
x
->andThen(x => Result.Ok(x)->resolve)
->catch(error => Result.Error(error)->resolve)
let mapResult =
(x: t<'ok>, ~ok, ~error): result<'ok, 'error> =>
x
->andThen(x => Result.Ok(x->ok)->resolve)
->catch(x => Result.Error(x->error)->resolve)
let mapOk =
(x: result<'ok, 'error>, fn: 'ok => 'ok'): result<'ok', 'error> =>
x->andThen(x =>
switch x {
| Result.Ok(x) => Result.Ok(x->fn)->resolve
| Result.Error(x) => Result.Error(x)->resolve
}
)
let mapError =
(x: result<'ok, 'error>, fn: 'error => 'error'): result<'ok, 'error'> =>
x->andThen(x =>
switch x {
| Result.Ok(x) => Result.Ok(x)->resolve
| Result.Error(x) => Result.Error(x->fn)->resolve
}
)
let wait =
(x: result<'ok, 'error>, fn: Result.t<'ok, 'error> => unit): unit =>
x
->andThen(x => x->fn->resolve)
->ignore
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment