A future should provide the fork, of, chain, and orElse methods, subject to the following rules:
- The
computationshould fulfil the type(α → γ), (β → γ) → γ. - The value should be stored in the internal field
[[Computation]], as-is. - If
computationis not a function, the behaviour is undefined.
- Should invoke the
[[Computation]]passingfas the first argument, andgas the second argument. - Should return whatever
[[Computation]]returns.
- The
ofmethod must return a Future containinga. - No parts of
ashould be checked.
fmust be an unary function that returns a Future.fwill be called with the successful value of the Future, if the Future contains a successful value.- If the future contains a successful value,
chainmust return a future equivalent to the one returned by applyingfto the successful value. - If the future contains an error value,
chainmust return a future equivalent to itself.
fmust be an unary function that returns a Future.fwill be called with the error value of the Future, if the Future contains an error.- If the Future contains a successful value,
orElsemust return a Future equivalent to itself. - If the Future contains an error value,
orElsemust return a Future equivalent to the one returned by applyingfto the error value.
Furthermore, the previous methods should satisfy the following equivalences:
p.chain(f).chain(g)=p.chain(x => f(x).chain(g))— associativityp.of(a).chain(f)=f(a)— left identityp.chain(p.of)=p— right identity
type Future[α, β] where
new :: ((α → γ), (β → γ) → γ) → Future[α, β]
fork :: @Future[α, β] => (α → γ), (β → γ) → γ
of :: β → Future[α, β]
chain :: (@Future[α, β]) => (β → Future[α, γ]) → Future[α, γ]
orElse :: (@Future[α, β]) => (α → Future[γ, β]) → Future[γ, β]