Creates a new Eval by applying a function to the successful
result of the source, and returns a new instance equivalent to
the result of the function.
const rndInt = Eval.of(() => {
const nr = Math.random() * 1000000
return nr & nr
})
const evenInt = () =>
rndInt.flatMap(int => {
if (i % 2 == 0)
return Eval.now(i)
else // Retry until we have an even number!
return evenInt()
})
Triggers the evaluation of the source, executing the given function for the generated element.
The application of this function has strict behavior, as the coeval is immediately executed.
Returns a new Eval that upon evaluation will execute the given
function for the generated element, transforming the source into
an Eval<void>.
Similar in spirit with normal .forEach, but lazy, as obviously nothing gets executed at this point.
Evaluates the source Eval and returns the result.
const ref = Eval.always(() => 100 * 2)
ref.get() // 200
Returns a new Eval that applies the mapping function to the
successful result emitted by the source.
Eval.now(111).map(_ => _ * 2).get() // 222
Memoizes (caches) the result of the source on the first
evaluation and reuses it on subsequent invocations of get().
The resulting Eval will be idempotent, meaning that
evaluating it multiple times will have the same effect
as evaluating it once.
Promote a thunk function to an Eval, catching exceptions in
the process.
Note that since Eval is not memoized by global, this will
recompute the value each time the Eval is executed.
Promote a thunk function generating Eval results to an Eval
of the same type.
Alias for Eval.suspend.
Maps 2 Eval values by the mapping function, returning a new
Eval reference that completes with the result of mapping that
function to the successful values of the futures, or in failure in
case either of them fails.
const fa1 = Eval.of(() => 1)
const fa2 = Eval.of(() => 2)
// Yields Success(3)
Eval.map2(fa1, fa2, (a, b) => a + b)
This operation is the Applicative.map2.
Maps 3 Eval values by the mapping function, returning a new
Eval reference that completes with the result of mapping that
function to the successful values of the futures, or in failure in
case either of them fails.
const fa1 = Eval.of(() => 1)
const fa2 = Eval.of(() => 2)
const fa3 = Eval.of(() => 3)
// Yields Success(6)
Eval.map3(fa1, fa2, fa3, (a, b, c) => a + b + c)
Maps 4 Eval values by the mapping function, returning a new
Eval reference that completes with the result of mapping that
function to the successful values of the futures, or in failure in
case either of them fails.
const fa1 = Eval.of(() => 1)
const fa2 = Eval.of(() => 2)
const fa3 = Eval.of(() => 3)
const fa4 = Eval.of(() => 4)
// Yields Success(10)
Eval.map4(fa1, fa2, fa3, fa4, (a, b, c, d) => a + b + c + d)
Maps 5 Eval values by the mapping function, returning a new
Eval reference that completes with the result of mapping that
function to the successful values of the futures, or in failure in
case either of them fails.
const fa1 = Eval.of(() => 1)
const fa2 = Eval.of(() => 2)
const fa3 = Eval.of(() => 3)
const fa4 = Eval.of(() => 4)
const fa5 = Eval.of(() => 5)
// Yields Success(15)
Eval.map5(fa1, fa2, fa3, fa4, fa5,
(a, b, c, d, e) => a + b + c + d + e
)
Maps 6 Eval values by the mapping function, returning a new
Eval reference that completes with the result of mapping that
function to the successful values of the futures, or in failure in
case either of them fails.
const fa1 = Eval.of(() => 1)
const fa2 = Eval.of(() => 2)
const fa3 = Eval.of(() => 3)
const fa4 = Eval.of(() => 4)
const fa5 = Eval.of(() => 5)
const fa6 = Eval.of(() => 6)
// Yields Success(21)
Eval.map6(
fa1, fa2, fa3, fa4, fa5, fa6,
(a, b, c, d, e, f) => a + b + c + d + e + f
)
Returns an Eval that on execution is always successful,
emitting the given strict value.
Alias for Eval.always.
Promote a thunk function to a Coeval that is memoized on the
first evaluation, the result being then available on subsequent
evaluations.
Note this is equivalent with:
Eval.always(thunk).memoize()
Transforms a list of Eval values into an Eval of a list.
Sample:
const io1 = Eval.of(() => 1)
const io2 = Eval.of(() => 2)
const io3 = Eval.of(() => 3)
// Yields [1, 2, 3]
const all: Eval<number[]> = Eval.sequence([f1, f2, f3])
Keeps calling f until a Right(b) is returned.
Based on Phil Freeman's Stack Safety for Free.
Described in FlatMap.tailRecM.
Shorthand for now(undefined as void), always returning
the same reference as optimization.
Generated using TypeDoc
Eval is a monad which controls evaluation.
This type wraps a value (or an expression that produces a value) and can produce it on command via the get() method.
There are three basic evaluation strategies:
Eval supports stack-safe lazy computation via the .map and .flatMap methods, which use an internal trampoline to avoid stack overflows. Computation done within
mapandflatMapis always done lazily, even when applied to anEval.nowinstance.Use
mapandflatMapto chain computation, and useget()to get the result when needed. It is also not good style to createEvalinstances whose computation involves callingget()on anotherEvalinstance -- this can defeat the trampolining and lead to stack overflows.const rndInt = Eval.of(() => { const nr = Math.random() * 1000000 return nr & nr }) const evenInt = () => rndInt.flatMap(int => { if (i % 2 == 0) return Eval.now(i) else // Retry until we have an even number! return evenInt() }) const cached = evenInt().memoize() // Nothing happens until now, this triggers the // actual evaluation: const n: number = cached.get()Versus IO
For dealing with lazy evaluation, the other alternative is the IO data type.
Differences between
EvalandIO:IOis capable of describing asynchronous computations as wellIOis capable of error handling (it implementsMonadError), whereasEvaldoes not provide error handling capabilities, being meant to be used for pure expressions (it implementsComonad, which is incompatible withMonadError)So if you need error handling capabilities (i.e.
MonadError<Throwable, ?>), or if you need to describe asynchronous processes, then IO is for you.Evalis a simpler data type with the sole purpose of controlling the evaluation of expressions (i.e. strict versus lazy).Credits
This type is inspired by
cats.Evalfrom Typelevel Cats and bymonix.eval.Coevalfrom Monix.