org.atnos.eff

Type members

Classlikes

final case
class AppendMemberIn[T[_], L, R, X](isRight: Boolean, member: MemberIn[T, X]) extends MemberIn[T, FxAppend[L, R]]
final case
class AppendMemberInOut[T[_], L, R, X](isRight: Boolean, append: MemberInOut[T, X]) extends MemberInOut[T, FxAppend[L, R]]
trait Augment[T[_], O[_]]
trait Batch

This trait provides a way to rewrite applicative effects when there is an operation allowing the batching of some effects based on the Batchable typeclass

This trait provides a way to rewrite applicative effects when there is an operation allowing the batching of some effects based on the Batchable typeclass

Companion
object
object Batch extends Batch
Companion
class
trait Batchable[T[_]]
trait Cache

This cache is used to memoize values for the Memoized effect

This cache is used to memoize values for the Memoized effect

sealed
trait Choose[T]
Companion
object
Companion
class

The Choose effect models non-determinism So we can get results, either:

The Choose effect models non-determinism So we can get results, either:

  • no results (when using ChooseZero)
  • the result for action1 or the result for action b (when using ChoosePlus)

When running this effect we can "collect" the results with any F which has an Alternative instance.

For example if F is List then:

  • no results is the empty list
  • the result for a or b is List(a, b)

If F is Option then:

  • no results is the None
  • the result for a or b is Some(a) or Some(b
Companion
object
object ChooseEffect extends ChooseEffect
Companion
class
Companion
object
Companion
class
case
object ChoosePlus extends Choose[Boolean]
case
class ChooseZero[T]() extends Choose[T]
case
class CollectedUnions[M[_], R, U](effects: Vector[M[Any]], otherEffects: Vector[Union[U, Any]], indices: Vector[Int], otherIndices: Vector[Int])

Collection of effects of a given type from a Unions objects

Collection of effects of a given type from a Unions objects

case
class ConcurrentHashMapCache(map: ConcurrentHashMap[AnyRef, Eval[Any]]) extends Cache
case
class Cons[H, T <: Members](head: H, tail: T) extends Members
Companion
object
object Cons extends ConsLower1
Companion
class
case
class Continuation[R, A, B](functions: Vector[Any => Eff[R, Any]], onNone: Last[R]) extends A => Eff[R, B]

Sequence of monadic functions from A to B: A => Eff[B]

Sequence of monadic functions from A to B: A => Eff[B]

Internally it is represented as a Vector of functions:

A => Eff[R, X1]; X1 => Eff[R, X2]; X2 => Eff[R, X3]; ...; X3 => Eff[R, B]

An alternate unit value can also be set on this function in case the argument A is not available. This value can be set by an effect to do some cleanup if it doesn't even get the chance to add its own effect. See SafeEffect.bracket

Companion
object
Companion
class
case
class Correct[E]() extends Validate[E, Unit]
sealed
trait Eff[R, A]

Effects of type R, returning a value of type A

Effects of type R, returning a value of type A

It is implemented as a "Free-er" monad with extensible effects:

  • the "pure" case is a pure value of type A

  • the "impure" case is:

    • a disjoint union of possible effects
    • a continuation of type X => Eff[R, A] indicating what to do if the current effect is of type M[X] this type is represented by the Arrs type
  • the "impure applicative" case is:

    • list of disjoint unions of possible effects
    • a function to apply to the values resulting from those effects

The monad implementation for this type is really simple:

  • point is Pure
  • bind simply appends the binding function to the Arrs continuation

Important:

The list of continuations is NOT implemented as a type sequence but simply as a

  Vector[Any => Eff[R, Any]]

This means that various .asInstanceOf are present in the implementation and could lead to burns and severe harm. Use with caution!

Similarly the list of effects in the applicative case is untyped and interpreters for those effects are supposed to create a list of values to feed the mapping function. If an interpreter doesn't create a list of values of the right size and with the right types, there will be a runtime exception.

The Pure, Impure and ImpureAp cases also incorporate a "last" action returning no value but just used for side-effects (shutting down an execution context for example). This action is meant to be executed at the end of all computations, regardless of the number of flatMaps added on the Eff value.

Since this last action will be executed, its value never collected so if it throws an exception it is possible to print it by defining the eff.debuglast system property (-Deff.debuglast=true)

See also
Companion
object
Companion
class
Companion
object
object EffCreation extends EffCreation
Companion
class
Companion
object
object EffImplicits extends EffImplicits
Companion
class
class EffImpossibleException(message: String) extends RuntimeException
Companion
object
Companion
class
sealed
trait Effect[R, A]

Union represents one effect T[_] embedded in a tree of possible effects R

Union represents one effect T[_] embedded in a tree of possible effects R

The effect tree is represented by four possible cases:

  • fx1[T]
  • fx2[T1, T2]
  • fx3[T1, T2, T3]
  • FxAppend[L, R]

The union type has three concrete constructors:

  • UnionAppendL(nested: Union[L]): Union[FxAppend[L, R]]
  • UnionAppendR(nested: Union[R]): Union[FxAppend[L, R]]
  • UnionTagged(valueUnsafe: Any, index: Int): Union[R] (for R in fx1, fx2, fx3...) In that respect UnionTagged behaves similarly to a tagged union in C or C++.
Companion
object
Companion
class

Effect for computation which can fail

Effect for computation which can fail

Companion
object
object EitherEffect extends EitherEffect
Companion
class
Companion
object
Companion
class
trait ErrorCreation[F] extends ErrorTypes[F]
trait ErrorEffect[F] extends ErrorCreation[F] with ErrorInterpretation[F]

Effect for computation which can fail and return a Throwable, or just stop with a failure

Effect for computation which can fail and return a Throwable, or just stop with a failure

This effect is a mix of Eval and Either in the sense that every computation passed to this effect (with the ok method) is considered "impure" or "faulty" by default.

The type F is used to represent the failure type.

Companion
object
object ErrorEffect extends ErrorEffect[String]

Simple instantiation of the ErrorEffect trait with String as a Failure type

Simple instantiation of the ErrorEffect trait with String as a Failure type

Companion
class
trait ErrorTypes[F]
trait EvalCreation extends EvalTypes

Effect for delayed computations

Effect for delayed computations

uses cats.Eval as a supporting data structure

Companion
object
object EvalEffect extends EvalEffect
Companion
class
Companion
object
trait EvalTypes
Companion
object
object EvalTypes extends EvalTypes
Companion
class
case
class Evaluate[F, A](run: Either[Either[Throwable, F], Eval[A]])
Companion
object
object Evaluate
Companion
class
case
class EvaluateValue[A](run: Eval[A]) extends Safe[A]
case
class ExecutorServices(executorServiceEval: Eval[ExecutorService], scheduledExecutorEval: Eval[ScheduledExecutorService], executionContextEval: Eval[ExecutionContext])
Companion
object
Companion
class
trait ExtractMember[T, +H]

Type class to extract members from a list of Member instances

Type class to extract members from a list of Member instances

Companion
object
Companion
class
case
class FailedFinalizer(t: Throwable) extends Safe[Unit]
case
class FailedValue[A](t: Throwable) extends Safe[A]
Companion
class
Companion
object
object FutureEffect extends FutureEffect
Companion
class
Companion
object
sealed
trait Fx

Base type for a tree of effect types

Base type for a tree of effect types

Companion
object
object Fx
Companion
class
trait Fx1[+F[_]] extends Fx
trait Fx2[+L[_], +R[_]] extends Fx
trait Fx3[+L[_], +M[_], +R[_]] extends Fx
trait FxAppend[+L, +R] extends Fx

Append a tree of effects to another one

Append a tree of effects to another one

case
class GetCache() extends Memoized[Cache]
case
class Impure[R, X, A](union: Effect[R, X], continuation: Continuation[R, X, A], last: Last[R]) extends Eff[R, A]

Impure is an effect (encoded as one possibility among other effects, a Union) and a continuation providing the next Eff value.

Impure is an effect (encoded as one possibility among other effects, a Union) and a continuation providing the next Eff value.

This essentially models a flatMap operation with the current effect and the monadic function to apply to a value once the effect is interpreted

One effect can always be executed last, just for side-effects

case
class ImpureAp[R, X, A](unions: Unions[R, X], continuation: Continuation[R, Vector[Any], A], last: Last[R]) extends Eff[R, A]

ImpureAp is a list of independent effects and a pure function creating a value with all the resulting values once all effects have been interpreted.

ImpureAp is a list of independent effects and a pure function creating a value with all the resulting values once all effects have been interpreted.

This essentially models a sequence + map operation but it is important to understand that the list of Union objects can represent different effects and be like: Vector[Option[Int], Future[String], Option[Int]].

Interpreting such an Eff value for a given effect (say Option) consists in:

  • grouping all the Option values,
  • sequencing them
  • pass them to a continuation which will apply the 'map' functions when the other effects (Future in the example above) will have been interpreted

VERY IMPORTANT:

  • this object is highly unsafe
  • the size of the list argument to 'map' must always be equal to the number of unions in the Unions object
  • the types of the elements in the list argument to 'map' must be the exact types of each effect in unions.unions
trait Interpret

The Interpret trait provides method to interpret (or "handle") effects.

The Interpret trait provides method to interpret (or "handle") effects.

An interpreter generally handles a given effect M and a value Eff[R, A] where M is a member of R.

The most general way of interpreting an effect is to implement the Interpreter trait for that effect and use the runInterpreter method. With the Interpreter trait you need to define:

  • what to do with pure values
  • what to do with an effect
  • what to do with a list of effects (the "applicative" case)
  • what to do with a "last" effect, in case of having side-effects to finalize resources (see the SafeEffect)

For each of those methods you get access to a continuation which you may or may not invoke to create the next effect in a sequence of effects. For example with the EitherEffect once you arrive on a Left value you don't trigger the continuation because there is no value to trigger it with.

There are also easier ways to define interpreters. The recurse method and the Recurser trait define:

  • onPure(a: A): B: how to map a pure value A to the result B
  • onEffect[X](mx: M[X]): X Either Eff[R, B]: either extract a value from the effect or return another effect
  • onApplicative[X](tx: T[M[X]]): T[X] Either M[T[X]]: either extract individual values from each effect or "sequence" the effect

Even simpler, the Translate trait does a translation from an effect M[X] to other effects in the stack.

There are also a few intercept methods to use an effect but still leave it in the stack

Companion
object
object Interpret extends Interpret
Companion
class
trait Interpreter[M[_], R, A, B]

Interpret eff values

Interpret eff values

For stack-safety reasons, the continuation must never be called with a value directly, but always with Eff.impure:

Eff.impure(a, continuation)

  • Note it is the responsibility of the implementation to call continuation.onNone if the continuation is not used to create the return value.
Companion
object
Companion
class
trait IntoPoly[R, U]

Typeclass proving that it is possible to send a tree of effects R into another tree of effects U

Typeclass proving that it is possible to send a tree of effects R into another tree of effects U

for example

Example
send[Option1, Fx.fx3[Option1, Option2, Option3], Int](Option1(1)).
  into[Fx.fx5[Option1, Option2, Option3, Option4, Option5]]

should work because all the effects of the first stack are present in the second Note: some implicit definitions are probably missing in some cases

Companion
object
object IntoPoly extends IntoPolyLower1
Companion
class
case
class Last[R](value: Option[Eval[Eff[R, Unit]]])

Encapsulation of one optional last action to execute at the end of the program

Encapsulation of one optional last action to execute at the end of the program

Companion
object
object Last
Companion
class
Companion
object
object ListCreation extends ListCreation
Companion
class

Effect for computations possibly returning several values

Effect for computations possibly returning several values

Companion
object
object ListEffect extends ListEffect
Companion
class
Companion
object
@implicitNotFound("No instance found for Member[${T}, ${R}].\nThe effect ${T} is not part of the stack ${R}\n or it was not possible to determine the stack that would result from removing ${T} from ${R}")
trait Member[T[_], R] extends MemberInOut[T, R]
Companion
object
object Member extends MemberLower1
Companion
class
@implicitNotFound("No instance found for MemberIn[${T}, ${R}].\nThe effect ${T} is not part of the stack ${R}")
trait MemberIn[T[_], R]
Companion
object
object MemberIn extends MemberInLower1
Companion
class
@implicitNotFound("No instance found for MemberInOut[${T}, ${R}].\nThe effect ${T} is not part of the stack ${R} or cannot be extracted from ${R}")
trait MemberInOut[T[_], R] extends MemberIn[T, R]
Companion
object
Companion
class
sealed
trait Members

list of Member instances for a given stack R

list of Member instances for a given stack R

Companion
object
object Members
Companion
class
trait MemoCreation extends MemoTypes

Memoization effect

Memoization effect

Memoize a computation for a given key

This effect can be interpreted with a cache implemented with many different libraries. See Cache.scala for 2 default implementations:

  • one concurrent hashmap (meaning an unbounded cache)
  • one concurrent hashmap with weak references (to evict entries based on garbage collection)

You can implement your own version using ScalaCache for example

Companion
object
object MemoEffect extends MemoEffect
Companion
class
Companion
object
trait MemoTypes
Companion
object
object MemoTypes extends MemoTypes
Companion
class
sealed
trait Memoized[A]
case
class NoEffect[R, A](a: A) extends Effect[R, A]
class NoFx extends Fx

The "empty" tree of effects

The "empty" tree of effects

Companion
object
object NoFx extends NoFx
Companion
class
case
class NoMember() extends Members
Companion
object
Companion
class

Effect for optional computations

Effect for optional computations

Companion
object
object OptionEffect extends OptionEffect
Companion
class
case
class Pure[R, A](value: A, last: Last[R]) extends Eff[R, A]
case
class Rand[A](run: Random => Option[A])

This class can be used as a F in runChoose to generate random alternatives

This class can be used as a F in runChoose to generate random alternatives

Companion
object
object Rand
Companion
class
Companion
object
Companion
class

Effect for computations depending on an environment.

Effect for computations depending on an environment.

The inside datatype for this effect is cats.data.Reader

Companion
object
object ReaderEffect extends ReaderEffect
Companion
class
trait Recurser[M[_], R, A, B]

Helper trait for computations which might produce several M[X] in a stack of effects.

Helper trait for computations which might produce several M[X] in a stack of effects.

Either we can produce an X to pass to a continuation or we're done

For the applicative case we expect to be able to traverse a list of effects and return an effect of a list of results OR completely consume the effect and return a pure list of values

trait RightFold[A, B]

support trait for folding values while possibly keeping some internal state

support trait for folding values while possibly keeping some internal state

sealed
trait Safe[A]

The Safe type is a mix of a ThrowableEither / Eval effect and a writer effect to collect finalizer failures

The Safe type is a mix of a ThrowableEither / Eval effect and a writer effect to collect finalizer failures

Companion
object
object Safe
Companion
class
trait SafeCreation extends SafeTypes
Companion
object
object SafeEffect extends SafeEffect
Companion
class
Companion
object
trait SafeTypes
trait SequenceCached[M[_]]

type class for effects which can be cached in a SequenceCache

type class for effects which can be cached in a SequenceCache

trait SideEffect[T[_]]
Companion
object
Companion
class

Effect for passing state along computations

Effect for passing state along computations

Internally backed up by cats.data.State

Companion
object
object StateEffect extends StateEffect
Companion
class
Companion
object
Companion
class
case
class Store[A](key: AnyRef, a: () => A) extends Memoized[A]

This effect is used in the implementation of the Async effect

This effect is used in the implementation of the Async effect

final case
class TaggedMemberIn[T[_], R](tag: Int) extends MemberIn[T, R]
final case
class TaggedMemberInOut[T[_], R](tag: Int) extends MemberInOut[T, R]
final case
class TimedFuture[A](callback: (Scheduler, ExecutionContext) => Future[A], timeout: Option[FiniteDuration])
Companion
object
Companion
class
trait Translate[T[_], U]

trait for translating one effect into other ones in the same stack

trait for translating one effect into other ones in the same stack

sealed
trait Union[R, A] extends Effect[R, A]
Companion
object
object Union
Companion
class
case
class UnionAppendL[L, R, A](value: Union[L, A]) extends Union[FxAppend[L, R], A]
case
class UnionAppendR[L, R, A](value: Union[R, A]) extends Union[FxAppend[L, R], A]
trait UnionInto[R, S]

transform a Union for a given stack into a Union for another stack

transform a Union for a given stack into a Union for another stack

case
class UnionTagged[R, A](valueUnsafe: Any, index: Int) extends Union[R, A]
case
class Unions[R, A](first: Union[R, A], rest: Vector[Union[R, Any]])

A non-empty list of Unions.

A non-empty list of Unions.

It is only partially typed, we just keep track of the type of the first object

Companion
object
object Unions
Companion
class
sealed
trait Validate[+E, A]
Companion
object
Companion
class

Effect for computation which can fail but will accumulate errors

Effect for computation which can fail but will accumulate errors

The runValidate interpreter just collects the messages and returns them at the end

Companion
object
Companion
class
case
class Warning[E](e: E) extends Validate[E, Unit]
trait Write[T[_], O]
Companion
object
Companion
class

Effect for logging values alongside computations

Effect for logging values alongside computations

Compared to traditional Writer monad which accumulates values by default this effect can be interpreted in different ways:

  • log values to the console or to a file as soon as they are produced
  • accumulate values in a list
Companion
object
object WriterEffect extends WriterEffect
Companion
class
case
class Wrong[E](e: E) extends Validate[E, Unit]
object batch extends Batch
object eff extends EffCreation with EffInterpretation
object interpret extends Interpret with Batch

Types

type /=[M[_], R] = MemberInOut[M, R]
type <=[M[_], R] = Member[M, R]
type |=[M[_], R] = MemberIn[M, R]