Options
All
  • Public
  • Public/Protected
  • All
Menu

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.now: for describing strict values, evaluated immediately
  • Eval.once: evaluated only once when the value is needed, with the result memoized (cached) for subsequent evaluations
  • Eval.always: evaluated every time the value is needed, being equivalent to a function

Eval supports stack-safe lazy computation via the .map and .flatMap methods, which use an internal trampoline to avoid stack overflows. Computation done within map and flatMap is always done lazily, even when applied to an Eval.now instance.

Use map and flatMap to chain computation, and use get() to get the result when needed. It is also not good style to create Eval instances whose computation involves calling get() on another Eval instance -- 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 Eval and IO:

  1. IO is capable of describing asynchronous computations as well
  2. IO is capable of error handling (it implements MonadError), whereas Eval does not provide error handling capabilities, being meant to be used for pure expressions (it implements Comonad, which is incompatible with MonadError)

So if you need error handling capabilities (i.e. MonadError<Throwable, ?>), or if you need to describe asynchronous processes, then IO is for you. Eval is 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.Eval from Typelevel Cats and by monix.eval.Coeval from Monix.

final

Type parameters

  • A

Hierarchy

  • Eval

Index

Methods

chain

  • chain<B>(f: function): Eval<B>

flatMap

  • flatMap<B>(f: function): Eval<B>
  • 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()
      })
    

    Type parameters

    • B

    Parameters

    • f: function
        • Parameters

          • a: A

          Returns Eval<B>

    Returns Eval<B>

forEach

  • forEach(cb: function): void
  • 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.

    Parameters

    • cb: function
        • (a: A): void
        • Parameters

          • a: A

          Returns void

    Returns void

forEachL

  • forEachL(cb: function): Eval<void>
  • 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.

    Parameters

    • cb: function
        • (a: A): void
        • Parameters

          • a: A

          Returns void

    Returns Eval<void>

get

  • get(): A
  • Evaluates the source Eval and returns the result.

    const ref = Eval.always(() => 100 * 2)
    
    ref.get() // 200
    

    Returns A

map

  • map<B>(f: function): Eval<B>
  • Returns a new Eval that applies the mapping function to the successful result emitted by the source.

    Eval.now(111).map(_ => _ * 2).get() // 222
    

    Type parameters

    • B

    Parameters

    • f: function
        • (a: A): B
        • Parameters

          • a: A

          Returns B

    Returns Eval<B>

memoize

  • memoize(): Eval<A>
  • 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.

    Returns Eval<A>

Static always

  • always<A>(thunk: function): Eval<A>
  • 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.

    Type parameters

    • A

    Parameters

    • thunk: function
        • (): A
        • Returns A

    Returns Eval<A>

Static defer

  • defer<A>(thunk: function): Eval<A>
  • Promote a thunk function generating Eval results to an Eval of the same type.

    Alias for Eval.suspend.

    Type parameters

    • A

    Parameters

    • thunk: function

    Returns Eval<A>

Static map2

  • map2<A1, A2, R>(fa1: Eval<A1>, fa2: Eval<A2>, f: function): Eval<R>
  • 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.

    Type parameters

    • A1

    • A2

    • R

    Parameters

    • fa1: Eval<A1>
    • fa2: Eval<A2>
    • f: function
        • (a1: A1, a2: A2): R
        • Parameters

          • a1: A1
          • a2: A2

          Returns R

    Returns Eval<R>

Static map3

  • map3<A1, A2, A3, R>(fa1: Eval<A1>, fa2: Eval<A2>, fa3: Eval<A3>, f: function): Eval<R>
  • 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)
    

    Type parameters

    • A1

    • A2

    • A3

    • R

    Parameters

    • fa1: Eval<A1>
    • fa2: Eval<A2>
    • fa3: Eval<A3>
    • f: function
        • (a1: A1, a2: A2, a3: A3): R
        • Parameters

          • a1: A1
          • a2: A2
          • a3: A3

          Returns R

    Returns Eval<R>

Static map4

  • map4<A1, A2, A3, A4, R>(fa1: Eval<A1>, fa2: Eval<A2>, fa3: Eval<A3>, fa4: Eval<A4>, f: function): Eval<R>
  • 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)
    

    Type parameters

    • A1

    • A2

    • A3

    • A4

    • R

    Parameters

    • fa1: Eval<A1>
    • fa2: Eval<A2>
    • fa3: Eval<A3>
    • fa4: Eval<A4>
    • f: function
        • (a1: A1, a2: A2, a3: A3, a4: A4): R
        • Parameters

          • a1: A1
          • a2: A2
          • a3: A3
          • a4: A4

          Returns R

    Returns Eval<R>

Static map5

  • map5<A1, A2, A3, A4, A5, R>(fa1: Eval<A1>, fa2: Eval<A2>, fa3: Eval<A3>, fa4: Eval<A4>, fa5: Eval<A5>, f: function): Eval<R>
  • 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
    )
    

    Type parameters

    • A1

    • A2

    • A3

    • A4

    • A5

    • R

    Parameters

    • fa1: Eval<A1>
    • fa2: Eval<A2>
    • fa3: Eval<A3>
    • fa4: Eval<A4>
    • fa5: Eval<A5>
    • f: function
        • (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5): R
        • Parameters

          • a1: A1
          • a2: A2
          • a3: A3
          • a4: A4
          • a5: A5

          Returns R

    Returns Eval<R>

Static map6

  • map6<A1, A2, A3, A4, A5, A6, R>(fa1: Eval<A1>, fa2: Eval<A2>, fa3: Eval<A3>, fa4: Eval<A4>, fa5: Eval<A5>, fa6: Eval<A6>, f: function): Eval<R>
  • 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
    )
    

    Type parameters

    • A1

    • A2

    • A3

    • A4

    • A5

    • A6

    • R

    Parameters

    • fa1: Eval<A1>
    • fa2: Eval<A2>
    • fa3: Eval<A3>
    • fa4: Eval<A4>
    • fa5: Eval<A5>
    • fa6: Eval<A6>
    • f: function
        • (a1: A1, a2: A2, a3: A3, a4: A4, a5: A5, a6: A6): R
        • Parameters

          • a1: A1
          • a2: A2
          • a3: A3
          • a4: A4
          • a5: A5
          • a6: A6

          Returns R

    Returns Eval<R>

Static now

  • now<A>(value: A): Eval<A>
  • Returns an Eval that on execution is always successful, emitting the given strict value.

    Type parameters

    • A

    Parameters

    • value: A

    Returns Eval<A>

Static of

  • of<A>(thunk: function): Eval<A>

Static once

  • once<A>(thunk: function): Eval<A>
  • 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()
    

    Type parameters

    • A

    Parameters

    • thunk: function
        • (): A
        • Returns A

    Returns Eval<A>

Static pure

  • pure<A>(value: A): Eval<A>
  • Lifts a value into the Eval context.

    Alias for Eval.now.

    Type parameters

    • A

    Parameters

    • value: A

    Returns Eval<A>

Static sequence

  • sequence<A>(list: Eval<A>[] | Iterable<Eval<A>>): Eval<A[]>
  • 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])
    

    Type parameters

    • A

    Parameters

    Returns Eval<A[]>

Static suspend

  • suspend<A>(thunk: function): Eval<A>
  • Promote a thunk function generating Eval results to an Eval of the same type.

    Type parameters

    • A

    Parameters

    • thunk: function

    Returns Eval<A>

Static tailRecM

  • tailRecM<A, B>(a: A, f: function): Eval<B>
  • Keeps calling f until a Right(b) is returned.

    Based on Phil Freeman's Stack Safety for Free.

    Described in FlatMap.tailRecM.

    Type parameters

    • A

    • B

    Parameters

    • a: A
    • f: function
        • (a: A): Eval<Either<A, B>>
        • Parameters

          • a: A

          Returns Eval<Either<A, B>>

    Returns Eval<B>

Static unit

  • unit(): Eval<void>
  • Shorthand for now(undefined as void), always returning the same reference as optimization.

    Returns Eval<void>

Legend

  • Module
  • Object literal
  • Variable
  • Function
  • Function with type parameter
  • Index signature
  • Type alias
  • Enumeration
  • Enumeration member
  • Property
  • Method
  • Interface
  • Interface with type parameter
  • Constructor
  • Property
  • Method
  • Index signature
  • Class
  • Class with type parameter
  • Constructor
  • Property
  • Method
  • Accessor
  • Index signature
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Inherited accessor
  • Protected property
  • Protected method
  • Protected accessor
  • Private property
  • Private method
  • Private accessor
  • Static property
  • Static method

Generated using TypeDoc