Evaluates the underlying computation and returns the result.
Evaluates the underlying computation and returns the result.
NOTE: this can throw exceptions.
// For didactic purposes, don't do shared vars at home :-) var i = 0 val fa = Coeval { i += 1; i } fa() //=> 1 fa() //=> 2 fa() //=> 3
Creates a new Coeval that will expose any triggered error from the source.
Creates a new Coeval that will expose any triggered error from the source.
val fa: Coeval[Int] = Coeval.raiseError[Int](new DummyException("dummy")) val fe: Coeval[Either[Throwable, Int]] = fa.attempt fe.flatMap { case Left(_) => Int.MaxValue case Right(v) => v }
By exposing errors by lifting the Coeval
's result into an
Either
value, we can handle those errors in flatMap
transformations.
Also see materialize for working with Scala's Try or transformWith for an alternative.
Dematerializes the source's result from a Try
.
Dematerializes the source's result from a Try
.
This equivalence always holds:
scala
fa.materialize.dematerialize <-> fa
Returns a new Coeval
in which f
is scheduled to be run on completion.
Returns a new Coeval
in which f
is scheduled to be run on completion.
This would typically be used to release any resources acquired by this
Coeval
.
Returns a failed projection of this coeval.
Returns a failed projection of this coeval.
The failed projection is a Coeval
holding a value of type Throwable
,
emitting the error yielded by the source, in case the source fails,
otherwise if the source succeeds the result will fail with a
NoSuchElementException
.
Creates a new Coeval
by applying a function to the successful result
of the source, and returns a new instance equivalent
to the result of the function.
Creates a new Coeval
by applying a function to the successful result
of the source, and returns a new instance equivalent
to the result of the function.
The application of flatMap
is always lazy and because of the
implementation it is memory safe and thus it can be used in
recursive loops.
Sample:
def randomEven: Coeval[Int] = Coeval(Random.nextInt()).flatMap { x => if (x < 0 || x % 2 == 1) randomEven // retry else Coeval.now(x) }
Given a source Coeval that emits another Coeval, this function flattens the result, returning a Coeval equivalent to the emitted Coeval by the source.
Given a source Coeval that emits another Coeval, this function flattens the result, returning a Coeval equivalent to the emitted Coeval by the source.
This equivalence with flatMap always holds:
scala
fa.flatten <-> fa.flatMap(x => x)
Triggers the evaluation of the source, executing the given function for the generated element.
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 task that upon evaluation will execute
the given function for the generated element,
transforming the source into a Coeval[Unit]
.
Returns a new task that upon evaluation will execute
the given function for the generated element,
transforming the source into a Coeval[Unit]
.
Similar in spirit with normal foreach, but lazy, as obviously nothing gets executed at this point.
Returns a new Coeval that applies the mapping function to the element emitted by the source.
Returns a new Coeval that applies the mapping function to the element emitted by the source.
Can be used for specifying a (lazy) transformation to the result of the source.
This equivalence with flatMap always holds:
scala
fa.map(f) <-> fa.flatMap(x => Coeval.pure(f(x)))
Creates a new Coeval that will expose any triggered error from the source.
Creates a new Coeval that will expose any triggered error from the source.
Also see attempt for working with Scala's Either or transformWith for an alternative.
Memoizes (caches) the result of the source and reuses it on
subsequent invocations of value
.
Memoizes (caches) the result of the source and reuses it on
subsequent invocations of value
.
The resulting coeval will be idempotent, meaning that evaluating the resulting coeval multiple times will have the same effect as evaluating it once.
memoizeOnSuccess for a version that only caches successful results
Memoizes (cache) the successful result of the source
and reuses it on subsequent invocations of value
.
Memoizes (cache) the successful result of the source
and reuses it on subsequent invocations of value
.
Thrown exceptions are not cached.
The resulting coeval will be idempotent, but only if the result is successful.
memoize for a version that caches both successful results and failures
Creates a new coeval that in case of error will fallback to the given backup coeval.
Creates a new coeval that will handle any matching throwable that this coeval might emit.
Creates a new coeval that will handle any matching throwable that this coeval might emit.
See onErrorRecover for the version that takes a partial function.
Creates a new coeval that will handle any matching throwable that this coeval might emit by executing another coeval.
Creates a new coeval that will handle any matching throwable that this coeval might emit by executing another coeval.
See onErrorRecoverWith for the version that takes a partial function.
Creates a new coeval that on error will try to map the error to another value using the provided partial function.
Creates a new coeval that on error will try to map the error to another value using the provided partial function.
See onErrorHandle for the version that takes a total function.
Creates a new coeval that will try recovering from an error by matching it with another coeval using the given partial function.
Creates a new coeval that will try recovering from an error by matching it with another coeval using the given partial function.
See onErrorHandleWith for the version that takes a total function.
Creates a new coeval that in case of error will retry executing the source again and again, until it succeeds.
Creates a new coeval that in case of error will retry executing the source again and again, until it succeeds.
In case of continuous failure the total number of executions
will be maxRetries + 1
.
Creates a new coeval that in case of error will retry executing the source again and again, until it succeeds.
Creates a new coeval that in case of error will retry executing the source again and again, until it succeeds.
In case of continuous failure the total number of executions
will be maxRetries + 1
.
Given a predicate function, keep retrying the coeval until the function returns true.
Evaluates the underlying computation, reducing this Coeval
to a Coeval.Eager value, with successful results being
signaled with Coeval.Now and failures with Coeval.Error.
Evaluates the underlying computation, reducing this Coeval
to a Coeval.Eager value, with successful results being
signaled with Coeval.Now and failures with Coeval.Error.
val fa = Coeval.eval(10 * 2) fa.run match { case Coeval.Now(value) => println("Success: " + value) case Coeval.Error(e) => e.printStackTrace() }
See runAttempt for working with Either values and runTry for working with Try values. See apply for a partial function (that may throw exceptions in case of failure).
Evaluates the underlying computation and returns the result or
any triggered errors as a Scala Either
, where Right(_)
is
for successful values and Left(_)
is for thrown errors.
Evaluates the underlying computation and returns the result or
any triggered errors as a Scala Either
, where Right(_)
is
for successful values and Left(_)
is for thrown errors.
val fa = Coeval(10 * 2) fa.runAttempt match { case Right(value) => println("Success: " + value) case Left(e) => e.printStackTrace() }
See run for working with Coeval.Eager values and runTry for working with Try values. See apply for a partial function (that may throw exceptions in case of failure).
Evaluates the underlying computation and returns the
result or any triggered errors as a scala.util.Try
.
Evaluates the underlying computation and returns the
result or any triggered errors as a scala.util.Try
.
val fa = Coeval(10 * 2) fa.runTry match { case Success(value) => println("Success: " + value) case Failure(e) => e.printStackTrace() }
See run for working with Coeval.Eager values and runAttempt for working with Either values. See apply for a partial function (that may throw exceptions in case of failure).
Converts the source Coeval into a cats.Eval
.
Converts the source Coeval into a cats.effect.IO
.
Creates a new Coeval
by applying the 'fa' function to the
successful result of this future, or the 'fe' function to the
potential errors that might happen.
Creates a new Coeval
by applying the 'fa' function to the
successful result of this future, or the 'fe' function to the
potential errors that might happen.
This function is similar with map, except that it can also transform errors and not just successful results.
For example attempt can be expressed in terms of transform
:
source.transform(v => Right(v), e => Left(e))
And materialize too:
source.transform(v => Success(v), e => Failure(e))
function that transforms a successful result of the receiver
function that transforms an error of the receiver
Creates a new Coeval
by applying the 'fa' function to the
successful result of this future, or the 'fe' function to the
potential errors that might happen.
Creates a new Coeval
by applying the 'fa' function to the
successful result of this future, or the 'fe' function to the
potential errors that might happen.
This function is similar with flatMap, except that it can also transform errors and not just successful results.
For example attempt can be expressed in terms of
transformWith
:
source.transformWith( v => Coeval.now(Right(v)), e => Coeval.now(Left(e)) )
function that transforms a successful result of the receiver
function that transforms an error of the receiver
Evaluates the underlying computation and returns the result.
Evaluates the underlying computation and returns the result.
NOTE: this can throw exceptions.
Alias for apply.
Zips the values of this
and that
coeval, and creates a new coeval
that will emit the tuple of their results.
Zips the values of this
and that
and applies the given
mapping function on their results.
Coeval
represents lazy computations that can execute synchronously.Word definition and origin:
Coeval
is the dual of an expression that evaluates to anA
.There are three evaluation strategies:
The
Once
andAlways
are both lazy strategies whileNow
andError
are eager.Once
andAlways
are distinguished from each other only by memoization: once evaluatedOnce
will save the value to be returned immediately if it is needed again.Always
will run its computation every time.Both
Now
andError
are represented by the Eager trait, a sub-type of Coeval that can be used as a replacement for Scala's ownTry
type.Coeval
supports stack-safe lazy computation via the .map and .flatMap methods, which use an internal trampoline to avoid stack overflows. Computations done within.map
and.flatMap
are always lazy, even when applied to a Coeval.Eager instance (e.g. Coeval.Now, Coeval.Error).Evaluation Strategies
The "now" and "raiseError" builders are building
Coeval
instances out of strict values:The "always" strategy is equivalent with a plain function:
The "once" strategy is equivalent with Scala's
lazy val
(along with thread-safe idempotency guarantees):Versus Task
The other option of suspending side-effects is Task. As a quick comparison:
Coeval
's execution is always immediate / synchronous, whereasTask
can describe asynchronous computationsCoeval
is not cancelable, obviously, since execution is immediate and there's nothing to cancelVersus cats.Eval
The
Coeval
data type is very similar with cats.Eval. As a quick comparison:cats.Eval
is only for controlling laziness, but it doesn't handle side effects, hencecats.Eval
is aComonad
Coeval
can handle side effects as well and thus it implementsMonadError[Coeval, Throwable]
andcats.effect.Sync
, providing error-handling utilitiesIf you just want to delay the evaluation of a pure expression use
cats.Eval
, but if you need to suspend side effects or you need error handling capabilities, then useCoeval
.