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
Source:
Batch.scala
object Batch extends Batch
Companion:
class
Source:
Batch.scala
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

Source:
Cache.scala
sealed trait Choose[T]
Companion:
object
Source:
Choose.scala
Companion:
class
Source:
Choose.scala

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
Source:
Choose.scala
object ChooseEffect extends ChooseEffect
Companion:
class
Source:
Choose.scala
Companion:
object
Source:
Choose.scala
Companion:
class
Source:
Choose.scala
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

Source:
Unions.scala
case class ConcurrentHashMapCache(map: ConcurrentHashMap[AnyRef, Eval[Any]]) extends Cache
case class Cons[H, T <: Members](head: H, tail: T) extends Members
Companion:
object
Source:
Members.scala
object Cons extends ConsLower1
Companion:
class
Source:
Members.scala
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
Source:
Continuation.scala
Companion:
class
Source:
Continuation.scala
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
Source:
Eff.scala
Companion:
class
Source:
Eff.scala
Companion:
object
Source:
Eff.scala
object EffCreation extends EffCreation
Companion:
class
Source:
Eff.scala
Companion:
object
Source:
Eff.scala
object EffImplicits extends EffImplicits
Companion:
class
Source:
Eff.scala
class EffImpossibleException(message: String) extends RuntimeException
Companion:
object
Source:
Eff.scala
Companion:
class
Source:
Eff.scala
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++.
Source:
Union.scala

Effect for computation which can fail

Effect for computation which can fail

Companion:
object
Source:
EitherEffect.scala
object EitherEffect extends EitherEffect
Companion:
class
Source:
EitherEffect.scala
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
Source:
ErrorEffect.scala

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
Source:
ErrorEffect.scala

Effect for delayed computations

Effect for delayed computations

uses cats.Eval as a supporting data structure

Companion:
object
Source:
EvalEffect.scala
object EvalEffect extends EvalEffect
Companion:
class
Source:
EvalEffect.scala
trait EvalTypes
Companion:
object
Source:
EvalEffect.scala
object EvalTypes extends EvalTypes
Companion:
class
Source:
EvalEffect.scala
case class Evaluate[F, A](run: Either[Either[Throwable, F], Eval[A]])
Companion:
object
Source:
ErrorEffect.scala
object Evaluate
Companion:
class
Source:
ErrorEffect.scala
case class EvaluateValue[A](run: Eval[A]) extends Safe[A]
case class ExecutorServices(executorServiceEval: Eval[ExecutorService], scheduledExecutorEval: Eval[ScheduledExecutorService], executionContextEval: Eval[ExecutionContext])
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
Source:
Members.scala
Companion:
class
Source:
Members.scala
case class FailedFinalizer(t: Throwable) extends Safe[Unit]
case class FailedValue[A](t: Throwable) extends Safe[A]
object FutureEffect extends FutureEffect
Companion:
class
Source:
FutureEffect.scala
sealed trait Fx

Base type for a tree of effect types

Base type for a tree of effect types

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

Append a tree of effects to another one

Append a tree of effects to another one

Source:
Fx.scala
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

Source:
Eff.scala
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
Source:
Eff.scala
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
Source:
Interpret.scala
object Interpret extends Interpret
Companion:
class
Source:
Interpret.scala
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
Source:
Interpret.scala
Companion:
class
Source:
Interpret.scala
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
Source:
IntoPoly.scala
object IntoPoly extends IntoPolyLower1
Companion:
class
Source:
IntoPoly.scala
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
Source:
Last.scala
object Last
Companion:
class
Source:
Last.scala
Companion:
object
Source:
ListEffect.scala
object ListCreation extends ListCreation
Companion:
class
Source:
ListEffect.scala

Effect for computations possibly returning several values

Effect for computations possibly returning several values

Companion:
object
Source:
ListEffect.scala
object ListEffect extends ListEffect
Companion:
class
Source:
ListEffect.scala
@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
Source:
Member.scala
object Member extends MemberLower1
Companion:
class
Source:
Member.scala
@implicitNotFound("No instance found for MemberIn[${T}, ${R}].\nThe effect ${T} is not part of the stack ${R}")
trait MemberIn[T[_], R]
Companion:
object
Source:
Member.scala
object MemberIn extends MemberInLower1
Companion:
class
Source:
Member.scala
@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
Source:
Member.scala
Companion:
class
Source:
Member.scala
sealed trait Members

list of Member instances for a given stack R

list of Member instances for a given stack R

Companion:
object
Source:
Members.scala
object Members
Companion:
class
Source:
Members.scala

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
Source:
MemoEffect.scala
object MemoEffect extends MemoEffect
Companion:
class
Source:
MemoEffect.scala
trait MemoTypes
Companion:
object
Source:
MemoEffect.scala
object MemoTypes extends MemoTypes
Companion:
class
Source:
MemoEffect.scala
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
Source:
Fx.scala
object NoFx extends NoFx
Companion:
class
Source:
Fx.scala
case class NoMember() extends Members

Effect for optional computations

Effect for optional computations

Companion:
object
Source:
OptionEffect.scala
object OptionEffect extends OptionEffect
Companion:
class
Source:
OptionEffect.scala
case class Pure[R, A](value: A, last: Last[R]) extends Eff[R, A]
Source:
Eff.scala
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
Source:
Choose.scala
object Rand
Companion:
class
Source:
Choose.scala

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
Source:
ReaderEffect.scala
object ReaderEffect extends ReaderEffect
Companion:
class
Source:
ReaderEffect.scala
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

Source:
Interpret.scala
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

Source:
WriterEffect.scala
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
Source:
SafeEffect.scala
object Safe
Companion:
class
Source:
SafeEffect.scala
object SafeEffect extends SafeEffect
Companion:
class
Source:
SafeEffect.scala
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

Source:
Cache.scala
trait SideEffect[T[_]]
Companion:
class
Source:
StateEffect.scala

Effect for passing state along computations

Effect for passing state along computations

Internally backed up by cats.data.State

Companion:
object
Source:
StateEffect.scala
object StateEffect extends StateEffect
Companion:
class
Source:
StateEffect.scala
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

Source:
SubscribeEffect.scala
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
Source:
FutureEffect.scala
Companion:
class
Source:
FutureEffect.scala
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

Source:
Interpret.scala
sealed trait Union[R, A] extends Effect[R, A]
Companion:
object
Source:
Union.scala
object Union
Companion:
class
Source:
Union.scala
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

Source:
Unions.scala
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
Source:
Unions.scala
object Unions
Companion:
class
Source:
Unions.scala
sealed trait Validate[+E, A]

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
Source:
ValidateEffect.scala
case class Warning[E](e: E) extends Validate[E, Unit]
trait Write[T[_], O]

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
Source:
WriterEffect.scala
object WriterEffect extends WriterEffect
Companion:
class
Source:
WriterEffect.scala
case class Wrong[E](e: E) extends Validate[E, Unit]
object batch extends Batch
Source:
all.scala
object interpret extends Interpret with Batch
Source:
all.scala
Source:
all.scala

Types

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