Interpret

trait Interpret

Support methods to create interpreters (or "effect handlers") for a given effect M and a value Eff[R, A] when M is a member of R.

Those methods guarantee a stack-safe behaviour when running on a large list of effects (in list.traverse(f) for example).

There are different types of supported interpreters:

  1. "interpret" + Recurse

This interpreter is used to handle effects which either return a value X from M[X] or stops with Eff[R, B] See an example of such an interpreter in Eval where we just evaluate a computation X for each Eval[X].

  1. "interpretState" + StateRecurse

This interpreter is used to handle effects which either return a value X from M[X] or stops with Eff[R, B]

  1. "interpretLoop" + Loop

The most generic kind of interpreter where we can even recurse in the case of Pure(a) (See ListEffect for such a use)

  1. "intercept / interceptState / interceptLoop" methods are similar but they transform an effect to other effects in the same stack without removing it from the stack

  2. "transform" to swap an effect T of a stack to another effect, using a Natural Transformation

  3. "translate" to interpret one effect of a stack into other effects of the same stack using a Natural Transformation this is a specialized version of interpret + Recurse

  4. "interpretUnsafe + SideEffect" when you have a side effecting function M[X] => X

Companion:
object
class Object
trait Matchable
class Any
object Interpret.type
object interpret.type

Type members

Classlikes

trait StateRecurse[M[_], A, B]

Helper trait for computations which might produce several M[X] in a stack of effects and which need to keep some state around

Helper trait for computations which might produce several M[X] in a stack of effects and which need to keep some state around

This is typically the case for Writer or State which need to keep some state S after each evaluation Evaluating the effect M[X] might use the previous S value as shown in the apply method

Finally when the Eff[R, A] returns an A, this one can be combined with the last state value to produce a B

Types

type of[F[_], G[_]] = { type l = [A] =>> F[G[A]]; }

Value members

Concrete methods

def augment[R, T[_], O[_], A](eff: Eff[R, A])(w: Augment[T, O])(implicit m: MemberInOut[T, R]): Eff[prepend[O, R], A]
def intercept[R, M[_], A, B](pure: A => Eff[R, B], recurse: Recurse[M, R, B])(effects: Eff[R, A])(implicit m: MemberInOut[M, R]): Eff[R, B]

INTERPRET IN THE SAME STACK

INTERPRET IN THE SAME STACK

def intercept1[R, M[_], A, B](pure: A => B)(recurse: Recurse[M, R, B])(effects: Eff[R, A])(implicit m: MemberInOut[M, R]): Eff[R, B]

simpler version of intercept where the pure value is just mapped to another type

simpler version of intercept where the pure value is just mapped to another type

def interceptLoop[R, M[_], A, B](pure: A => Eff[R, B], loop: Loop[M, R, A, Eff[R, B], Eff[R, Unit]])(effects: Eff[R, A])(implicit m: MemberInOut[M, R]): Eff[R, B]

intercept an effect and interpret it in the same stack. This method is stack-safe

intercept an effect and interpret it in the same stack. This method is stack-safe

def interceptLoop1[R, M[_], A, B](pure: A => B)(loop: Loop[M, R, A, Eff[R, B], Eff[R, Unit]])(effects: Eff[R, A])(implicit m: MemberInOut[M, R]): Eff[R, B]
def interceptNat[R, T[_], A](effects: Eff[R, A])(nat: NaturalTransformation[T, T])(implicit m: MemberInOut[T, R]): Eff[R, A]

Intercept the values for one effect and transform them into other values for the same effect

Intercept the values for one effect and transform them into other values for the same effect

def interceptNatM[R, T[_], F[_], A](effects: Eff[R, A], nat: NaturalTransformation[T, <none>])(implicit m: MemberInOut[T, R], FT: Traverse[F], FM: Monad[F]): Eff[R, F[A]]

Intercept the values for one effect, emitting new values for the same effect inside a monad which is interleaved in

Intercept the values for one effect, emitting new values for the same effect inside a monad which is interleaved in

def interceptStatelessLoop[R, M[_], A, B](pure: A => Eff[R, B], loop: StatelessLoop[M, R, A, Eff[R, B], Eff[R, Unit]])(effects: Eff[R, A])(implicit m: MemberInOut[M, R]): Eff[R, B]
def interceptStatelessLoop1[R, M[_], A, B](pure: A => B)(loop: StatelessLoop[M, R, A, Eff[R, B], Eff[R, Unit]])(effects: Eff[R, A])(implicit m: MemberInOut[M, R]): Eff[R, B]
def interpret[R, U, M[_], A, B](pure: A => Eff[U, B], recurse: Recurse[M, U, B])(effects: Eff[R, A])(implicit m: Aux[M, R, U]): Eff[U, B]

interpret the effect M in the R stack

interpret the effect M in the R stack

def interpret1[R, U, M[_], A, B](pure: A => B)(recurse: Recurse[M, U, B])(effects: Eff[R, A])(implicit m: Aux[M, R, U]): Eff[U, B]

simpler version of interpret where the pure value is just mapped to another type

simpler version of interpret where the pure value is just mapped to another type

def interpretLoop[R, U, M[_], A, B](pure: A => Eff[U, B], loop: Loop[M, R, A, Eff[U, B], Eff[U, Unit]])(effects: Eff[R, A])(implicit m: Aux[M, R, U]): Eff[U, B]

generalization of interpret and interpretState

generalization of interpret and interpretState

This method contains a loop which is stack-safe

def interpretLoop1[R, U, M[_], A, B](pure: A => B)(loop: Loop[M, R, A, Eff[U, B], Eff[U, Unit]])(effects: Eff[R, A])(implicit m: Aux[M, R, U]): Eff[U, B]
def interpretState[R, U, M[_], A, B](pure: A => Eff[U, B], recurse: StateRecurse[M, A, B])(effects: Eff[R, A])(implicit m: Aux[M, R, U]): Eff[U, B]

interpret the effect M in the M |: R stack, keeping track of some state

interpret the effect M in the M |: R stack, keeping track of some state

def interpretState1[R, U, M[_], A, B](pure: A => B)(recurse: StateRecurse[M, A, B])(effects: Eff[R, A])(implicit m: Aux[M, R, U]): Eff[U, B]

simpler version of interpret1 where the pure value is just mapped to another type

simpler version of interpret1 where the pure value is just mapped to another type

def interpretStatelessLoop[R, U, M[_], A, B](pure: A => Eff[U, B], loop: StatelessLoop[M, R, A, Eff[U, B], Eff[U, Unit]])(effects: Eff[R, A])(implicit m: Aux[M, R, U]): Eff[U, B]

generalization of interpret

generalization of interpret

This method contains a loop which is stack-safe

def interpretStatelessLoop1[R, U, M[_], A, B](pure: A => B)(loop: StatelessLoop[M, R, A, Eff[U, B], Eff[U, Unit]])(effects: Eff[R, A])(implicit m: Aux[M, R, U]): Eff[U, B]
def interpretUnsafe[R, U, T[_], A](effects: Eff[R, A])(sideEffect: SideEffect[T])(implicit m: Aux[T, R, U]): Eff[U, A]

interpret an effect by running side-effects

interpret an effect by running side-effects

def transform[SR, BR, U, TS[_], TB[_], A](r: Eff[SR, A], nat: NaturalTransformation[TS, TB])(implicit sr: Aux[TS, SR, U], br: Aux[TB, BR, U]): Eff[BR, A]

transform an effect into another one using a natural transformation, leaving the rest of the stack untouched

transform an effect into another one using a natural transformation, leaving the rest of the stack untouched

def translate[R, U, T[_], A](effects: Eff[R, A])(tr: Translate[T, U])(implicit m: Aux[T, R, U]): Eff[U, A]

Translate one effect of the stack into some of the other effects in the stack

Translate one effect of the stack into some of the other effects in the stack

def translateInto[R, T[_], U, A](eff: Eff[R, A])(translate: Translate[T, U])(implicit m: MemberInOut[T, R], into: IntoPoly[R, U]): Eff[U, A]

Translate one effect of the stack into other effects in a larger stack

Translate one effect of the stack into other effects in a larger stack

def translateNat[R, U, T[_], A](effects: Eff[R, A])(nat: NaturalTransformation[T, [_] =>> Eff[U, _$43]])(implicit m: Aux[T, R, U]): Eff[U, A]

Translate one effect of the stack into some of the other effects in the stack Using a natural transformation

Translate one effect of the stack into some of the other effects in the stack Using a natural transformation