A pure abstraction representing the intention to perform a side effect, where the result of that side effect may be obtained synchronously (via return) or asynchronously (via callback).
IO
values are pure, immutable values and thus preserve referential transparency, being
usable in functional programming. An IO
is a data structure that represents just a
description of a side effectful computation.
IO
can describe synchronous or asynchronous computations that:
- on evaluation yield exactly one result 2. can end in either success or failure and in
case of failure
flatMap
chains get short-circuited (IO
implementing the algebra ofMonadError
) 3. can be canceled, but note this capability relies on the user to provide cancelation logic
Effects described via this abstraction are not evaluated until the "end of the world", which is to say, when one of the "unsafe" methods are used. Effectful results are not memoized, meaning that memory overhead is minimal (and no leaks), and also that a single effect may be run multiple times in a referentially-transparent manner. For example:
val ioa = IO.println("hey!")
val program = for {
_ <- ioa
_ <- ioa
} yield ()
program.unsafeRunSync()
The above will print "hey!" twice, as the effect will be re-run each time it is sequenced in the monadic chain.
IO
is trampolined in its flatMap
evaluation. This means that you can safely call
flatMap
in a recursive function of arbitrary depth, without fear of blowing the stack.
def fib(n: Int, a: Long = 0, b: Long = 1): IO[Long] =
IO.pure(a + b) flatMap { b2 =>
if (n > 0)
fib(n - 1, b, b2)
else
IO.pure(a)
}
Attributes
Members list
Value members
Concrete methods
Runs this IO and the parameter in parallel.
Runs this IO and the parameter in parallel.
Failure in either of the IOs will cancel the other one. If the whole computation is canceled, both actions are also canceled.
Attributes
- Source:
- IO.scala
Runs the current IO, then runs the parameter, keeping its result. The result of the first action is ignored. If the source fails, the other action won't run. Not suitable for use when the parameter is a recursive reference to the current expression.
Runs the current IO, then runs the parameter, keeping its result. The result of the first action is ignored. If the source fails, the other action won't run. Not suitable for use when the parameter is a recursive reference to the current expression.
Attributes
Runs the current IO, then runs the parameter, keeping its result. The result of the first action is ignored. If the source fails, the other action won't run. Evaluation of the parameter is done lazily, making this suitable for recursion.
Runs the current IO, then runs the parameter, keeping its result. The result of the first action is ignored. If the source fails, the other action won't run. Evaluation of the parameter is done lazily, making this suitable for recursion.
Attributes
- See also:
[*>] for the strictly evaluated alternative
- Source:
- IO.scala
Returns an IO that will wait for the given duration after the execution of the source before returning the result.
Returns an IO that will wait for the given duration after the execution of the source before returning the result.
Attributes
- duration
The duration to wait after executing the source
- Source:
- IO.scala
Replaces the result of this IO with the given value.
Materializes any sequenced exceptions into value space, where they may be handled.
Materializes any sequenced exceptions into value space, where they may be handled.
This is analogous to the catch
clause in try
/catch
, being the inverse of
IO.raiseError
. Thus:
IO.raiseError(ex).attempt.unsafeRunSync() === Left(ex)
Attributes
- See also:
- Source:
- IO.scala
Returns a resource that will start execution of this IO in the background.
Returns a resource that will start execution of this IO in the background.
In case the resource is closed while this IO is still running (e.g. due to a failure in
use
), the background action will be canceled.
Attributes
- See also:
cats.effect.kernel.GenSpawn#background for the generic version.
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Runs the current and given IO in parallel, producing the pair of the results. If either fails with an error, the result of the whole will be that error and the other will be canceled.
Runs the current and given IO in parallel, producing the pair of the results. If either fails with an error, the result of the whole will be that error and the other will be canceled.
Attributes
- See also:
bothOutcome for the version which produces the outcome of both effects executed in parallel
race for the version which produces the result of the winner and cancels the loser of the race
- Source:
- IO.scala
Runs the current and given IO in parallel, producing the pair of the outcomes. Both outcomes are produced, regardless of whether they complete successfully.
Runs the current and given IO in parallel, producing the pair of the outcomes. Both outcomes are produced, regardless of whether they complete successfully.
Attributes
- See also:
both for the version which embeds the outcomes to produce a pair of the results
raceOutcome for the version which produces the outcome of the winner and cancels the loser of the race
- Source:
- IO.scala
Returns an IO
action that treats the source task as the acquisition of a resource, which
is then exploited by the use
function and then released
.
Returns an IO
action that treats the source task as the acquisition of a resource, which
is then exploited by the use
function and then released
.
The bracket
operation is the equivalent of the try {} catch {} finally {}
statements
from mainstream languages.
The bracket
operation installs the necessary exception handler to release the resource in
the event of an exception being raised during the computation, or in case of cancelation.
If an exception is raised, then bracket
will re-raise the exception ''after'' performing
the release
. If the resulting task gets canceled, then bracket
will still perform the
release
, but the yielded task will be non-terminating (equivalent with IO.never).
Example:
import java.io._
def readFile(file: File): IO[String] = {
// Opening a file handle for reading text
val acquire = IO(new BufferedReader(
new InputStreamReader(new FileInputStream(file), "utf-8")
))
acquire.bracket { in =>
// Usage part
IO {
// Yes, ugly Java, non-FP loop;
// side-effects are suspended though
var line: String = null
val buff = new StringBuilder()
do {
line = in.readLine()
if (line != null) buff.append(line)
} while (line != null)
buff.toString()
}
} { in =>
// The release part
IO(in.close())
}
}
Note that in case of cancelation the underlying implementation cannot guarantee that the
computation described by use
doesn't end up executed concurrently with the computation
from release
. In the example above that ugly Java loop might end up reading from a
BufferedReader
that is already closed due to the task being canceled, thus triggering an
error in the background with nowhere to get signaled.
In this particular example, given that we are just reading from a file, it doesn't matter. But in other cases it might matter, as concurrency on top of the JVM when dealing with I/O might lead to corrupted data.
For those cases you might want to do synchronization (e.g. usage of locks and semaphores) and you might want to use bracketCase, the version that allows you to differentiate between normal termination and cancelation.
'''NOTE on error handling''': in case both the release
function and the use
function
throws, the error raised by release
gets signaled.
For example:
val foo = new RuntimeException("Foo")
val bar = new RuntimeException("Bar")
IO("resource").bracket { _ =>
// use
IO.raiseError(foo)
} { _ =>
// release
IO.raiseError(bar)
}
In this case the resulting IO
will raise error foo
, while the bar
error gets reported
on a side-channel. This is consistent with the behavior of Java's "Try with resources"
except that no involved exceptions are mutated (i.e., in contrast to Java, bar
isn't
added as a suppressed exception to foo
).
Attributes
- release
is a function that gets called after
use
terminates, either normally or in error, or if it gets canceled, receiving as input the resource that needs to be released- use
is a function that evaluates the resource yielded by the source, yielding a result that will get generated by the task returned by this
bracket
function- See also:
- Source:
- IO.scala
Returns a new IO
task that treats the source task as the acquisition of a resource, which
is then exploited by the use
function and then released
, with the possibility of
distinguishing between normal termination and cancelation, such that an appropriate release
of resources can be executed.
Returns a new IO
task that treats the source task as the acquisition of a resource, which
is then exploited by the use
function and then released
, with the possibility of
distinguishing between normal termination and cancelation, such that an appropriate release
of resources can be executed.
The bracketCase
operation is the equivalent of try {} catch {} finally {}
statements
from mainstream languages when used for the acquisition and release of resources.
The bracketCase
operation installs the necessary exception handler to release the
resource in the event of an exception being raised during the computation, or in case of
cancelation.
In comparison with the simpler bracket version, this one allows the caller to differentiate between normal termination, termination in error and cancelation via an Outcome parameter.
Attributes
- release
is a function that gets called after
use
terminates, either normally or in error, or if it gets canceled, receiving as input the resource that needs release, along with the result ofuse
(cancelation, error or successful result)- use
is a function that evaluates the resource yielded by the source, yielding a result that will get generated by this function on evaluation
- See also:
- Source:
- IO.scala
Logs the value of this IO
(even if it is an error or if it was cancelled) to the
standard output, using the implicit cats.Show
instance.
Logs the value of this IO
(even if it is an error or if it was cancelled) to the
standard output, using the implicit cats.Show
instance.
This operation is intended as a quick debug, not as proper logging.
Attributes
- prefix
A custom prefix for the log message,
DEBUG
is used as the default.- Source:
- IO.scala
Returns an IO that will delay the execution of the source by the given duration.
Returns an IO that will delay the execution of the source by the given duration.
Attributes
- duration
The duration to wait before executing the source
- Source:
- IO.scala
Shifts the execution of the current IO to the specified ExecutionContext
. All stages of
the execution will default to the pool in question, and any asynchronous callbacks will
shift back to the pool upon completion. Any nested use of evalOn
will override the
specified pool. Once the execution fully completes, default control will be shifted back to
the enclosing (inherited) pool.
Shifts the execution of the current IO to the specified ExecutionContext
. All stages of
the execution will default to the pool in question, and any asynchronous callbacks will
shift back to the pool upon completion. Any nested use of evalOn
will override the
specified pool. Once the execution fully completes, default control will be shifted back to
the enclosing (inherited) pool.
Attributes
- See also:
IO.executionContext for obtaining the
ExecutionContext
on which the currentIO
is being executed- Source:
- IO.scala
Monadic bind on IO
, used for sequentially composing two IO
actions, where the value
produced by the first IO
is passed as input to a function producing the second IO
action.
Monadic bind on IO
, used for sequentially composing two IO
actions, where the value
produced by the first IO
is passed as input to a function producing the second IO
action.
Due to this operation's signature, flatMap
forces a data dependency between two IO
actions, thus ensuring sequencing (e.g. one action to be executed before another one).
Any exceptions thrown within the function will be caught and sequenced into the IO
,
because due to the nature of asynchronous processes, without catching and handling
exceptions, failures would be completely silent and IO
references would never terminate
on evaluation.
Attributes
- Source:
- IO.scala
Evaluates the current IO
in an infinite loop, terminating only on error or cancelation.
Evaluates the current IO
in an infinite loop, terminating only on error or cancelation.
IO.println("Hello, World!").foreverM // continues printing forever
Attributes
- Source:
- IO.scala
Executes the given finalizer
when the source is finished, either in success or in error,
or if canceled.
Executes the given finalizer
when the source is finished, either in success or in error,
or if canceled.
This variant of guaranteeCase evaluates the given finalizer
regardless of how the
source gets terminated:
- normal completion
- completion in error
- cancelation
This equivalence always holds:
io.guarantee(f) <-> IO.unit.bracket(_ => io)(_ => f)
Attributes
- See also:
guaranteeCase for the version that can discriminate between termination conditions
- Source:
- IO.scala
Executes the given finalizer
when the source is finished, either in success or in error,
or if canceled, allowing for differentiating between exit conditions.
Executes the given finalizer
when the source is finished, either in success or in error,
or if canceled, allowing for differentiating between exit conditions.
This variant of guarantee injects an Outcome in the provided function, allowing one to make a difference between:
- normal completion
- completion in error
- cancelation
This equivalence always holds:
io.guaranteeCase(f) <-> IO.unit.bracketCase(_ => io)((_, e) => f(e))
Attributes
Attributes
- Source:
- IO.scala
Handle any error, potentially recovering from it, by mapping it to another IO
value.
Handle any error, potentially recovering from it, by mapping it to another IO
value.
Implements ApplicativeError.handleErrorWith
.
Attributes
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Functor map on IO
. Given a mapping function, it transforms the value produced by the
source, while keeping the IO
context.
Functor map on IO
. Given a mapping function, it transforms the value produced by the
source, while keeping the IO
context.
Any exceptions thrown within the function will be caught and sequenced into the IO
. Due
to the nature of asynchronous processes, without catching and handling exceptions, failures
would be completely silent and IO
references would never terminate on evaluation.
Attributes
- Source:
- IO.scala
Replaces failures in this IO with an empty Option.
Runs the current IO, if it fails with an error(exception), the other IO will be executed.
Runs the current IO, if it fails with an error(exception), the other IO will be executed.
Attributes
- other
IO to be executed (if the current IO fails)
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Recover from certain errors by mapping them to an A
value.
Recover from certain errors by mapping them to an A
value.
Implements ApplicativeError.recover
.
Attributes
- Source:
- IO.scala
Recover from certain errors by mapping them to another IO
value.
Recover from certain errors by mapping them to another IO
value.
Implements ApplicativeError.recoverWith
.
Attributes
- Source:
- IO.scala
Returns a new value that transforms the result of the source, given the recover
or map
functions, which get executed depending on whether the result ends in error or if it is
successful.
Returns a new value that transforms the result of the source, given the recover
or map
functions, which get executed depending on whether the result ends in error or if it is
successful.
This is an optimization on usage of attempt and map, this equivalence being true:
io.redeem(recover, map) <-> io.attempt.map(_.fold(recover, map))
Usage of redeem
subsumes handleError
because:
io.redeem(fe, id) <-> io.handleError(fe)
Attributes
- map
is a function used for mapping the result of the source in case it ends in success
- recover
is a function used for error recover in case the source ends in error
- Source:
- IO.scala
Returns a new value that transforms the result of the source, given the recover
or bind
functions, which get executed depending on whether the result ends in error or if it is
successful.
Returns a new value that transforms the result of the source, given the recover
or bind
functions, which get executed depending on whether the result ends in error or if it is
successful.
This is an optimization on usage of attempt and flatMap, this equivalence being available:
io.redeemWith(recover, bind) <-> io.attempt.flatMap(_.fold(recover, bind))
Usage of redeemWith
subsumes handleErrorWith
because:
io.redeemWith(fe, F.pure) <-> io.handleErrorWith(fe)
Usage of redeemWith
also subsumes flatMap because:
io.redeemWith(F.raiseError, fs) <-> io.flatMap(fs)
Attributes
- bind
is the function that gets to transform the source in case of success
- recover
is the function that gets called to recover the source in case of error
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Inverse of attempt
Inverse of attempt
This function raises any materialized error.
IO(Right(a)).rethrow === IO.pure(a)
IO(Left(ex)).rethrow === IO.raiseError(ex)
// Or more generally:
io.attempt.rethrow === io // For any io.
Attributes
- See also:
- Source:
- IO.scala
Start execution of the source suspended in the IO
context.
Start execution of the source suspended in the IO
context.
This can be used for non-deterministic / concurrent execution. The following code is more
or less equivalent with parMap2
(minus the behavior on error handling and cancelation):
def par2[A, B](ioa: IO[A], iob: IO[B]): IO[(A, B)] =
for {
fa <- ioa.start
fb <- iob.start
a <- fa.join
b <- fb.join
} yield (a, b)
Note in such a case usage of parMapN
(via cats.Parallel
) is still recommended because
of behavior on error and cancelation — consider in the example above what would happen if
the first task finishes in error. In that case the second task doesn't get canceled, which
creates a potential memory leak.
Also see background for a safer alternative.
Attributes
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Translates this IO[A]
into a SyncIO
value which, when evaluated, runs the original IO
to its completion, the limit
number of stages, or until the first stage that cannot be
expressed with SyncIO
(typically an asynchronous boundary).
Translates this IO[A]
into a SyncIO
value which, when evaluated, runs the original IO
to its completion, the limit
number of stages, or until the first stage that cannot be
expressed with SyncIO
(typically an asynchronous boundary).
Attributes
- limit
The maximum number of stages to evaluate prior to forcibly yielding to
IO
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Returns an IO that either completes with the result of the source within the specified time
duration
or otherwise raises a TimeoutException
.
Returns an IO that either completes with the result of the source within the specified time
duration
or otherwise raises a TimeoutException
.
The source is canceled in the event that it takes longer than the specified time duration
to complete. Once the source has been successfully canceled (and has completed its
finalizers), the TimeoutException
will be raised. If the source is uncancelable, the
resulting effect will wait for it to complete before raising the exception.
Attributes
- duration
is the time span for which we wait for the source to complete; in the event that the specified time has passed without the source completing, a
TimeoutException
is raised- Source:
- IO.scala
Returns an IO that either completes with the result of the source within the specified time
duration
or otherwise raises a TimeoutException
.
Returns an IO that either completes with the result of the source within the specified time
duration
or otherwise raises a TimeoutException
.
The source is canceled in the event that it takes longer than the specified time duration to complete. Unlike timeout, the cancelation of the source will be ''requested'' but not awaited, and the exception will be raised immediately upon the completion of the timer. This may more closely match intuitions about timeouts, but it also violates backpressure guarantees and intentionally leaks fibers.
This combinator should be applied very carefully.
Attributes
- duration
The time span for which we wait for the source to complete; in the event that the specified time has passed without the source completing, a
TimeoutException
is raised- See also:
timeout for a variant which respects backpressure and does not leak fibers
- Source:
- IO.scala
Returns an IO that either completes with the result of the source within the specified time
duration
or otherwise evaluates the fallback
.
Returns an IO that either completes with the result of the source within the specified time
duration
or otherwise evaluates the fallback
.
The source is canceled in the event that it takes longer than the specified time duration to complete. Once the source has been successfully canceled (and has completed its finalizers), the fallback will be sequenced. If the source is uncancelable, the resulting effect will wait for it to complete before evaluating the fallback.
Attributes
- duration
is the time span for which we wait for the source to complete; in the event that the specified time has passed without the source completing, the
fallback
gets evaluated- fallback
is the task evaluated after the duration has passed and the source canceled
- Source:
- IO.scala
Returns a string representation of the object.
Returns a string representation of the object.
The default representation is platform dependent.
Attributes
- Returns:
a string representation of the object.
- Definition Classes
- Any
- Source:
- IO.scala
Makes the source IO
uninterruptible such that a cats.effect.kernel.Fiber#cancel
signal is ignored until completion.
Makes the source IO
uninterruptible such that a cats.effect.kernel.Fiber#cancel
signal is ignored until completion.
Attributes
- See also:
IO.uncancelable for constructing uncancelable
IO
values with user-configurable cancelable regions- Source:
- IO.scala
Triggers the evaluation of the source and any suspended side effects therein, but ignores the result.
Triggers the evaluation of the source and any suspended side effects therein, but ignores the result.
This operation is similar to unsafeRunAsync, in that the evaluation can happen asynchronously, except no callback is required and therefore the result is ignored.
Note that errors still get logged (via IO's internal logger), because errors being thrown should never be totally silent.
Attributes
- Source:
- IO.scala
Passes the result of the encapsulated effects to the given callback by running them as impure side effects.
Passes the result of the encapsulated effects to the given callback by running them as impure side effects.
Any exceptions raised within the effect will be passed to the callback in the Either
. The
callback will be invoked at most once. In addition, fatal errors will be printed. Note
that it is very possible to construct an IO which never returns while still never blocking
a thread, and attempting to evaluate that IO with this method will result in a situation
where the callback is never invoked.
As the name says, this is an UNSAFE function as it is impure and performs side effects. You should ideally only call this function ''once'', at the very end of your program.
Attributes
- Source:
- IO.scala
Attributes
- Source:
- IO.scala
Evaluates the effect, returning a cancelation token that can be used to cancel it.
Evaluates the effect, returning a cancelation token that can be used to cancel it.
This is similar to unsafeRunAsync
in that it evaluates the IO
as a side effect in a
non-blocking fashion, but uses a Future
rather than an explicit callback. This function
should really only be used if interoperating with code which uses Scala futures.
Attributes
- See also:
- Source:
- IO.scala
Evaluates the effect and produces the result in a Future
.
Evaluates the effect and produces the result in a Future
.
This is similar to unsafeRunAsync
in that it evaluates the IO
as a side effect in a
non-blocking fashion, but uses a Future
rather than an explicit callback. This function
should really only be used if interoperating with code which uses Scala futures.
Attributes
- See also:
- Source:
- IO.scala
Evaluates the effect and produces the result in a Future
, along with a cancelation token
that can be used to cancel the original effect.
Evaluates the effect and produces the result in a Future
, along with a cancelation token
that can be used to cancel the original effect.
This is similar to unsafeRunAsync
in that it evaluates the IO
as a side effect in a
non-blocking fashion, but uses a Future
rather than an explicit callback. This function
should really only be used if interoperating with code which uses Scala futures.
Attributes
- See also:
- Source:
- IO.scala
Ignores the result of this IO.
Inherited methods
Evaluates the effect and produces the result in a Future
.
Evaluates the effect and produces the result in a Future
.
This is similar to unsafeToFuture
in that it evaluates the IO
as a side effect in a
non-blocking fashion, but begins by taking a syncStep
limited by the runtime's auto-yield
threshold. This function should really only be used if it is critical to attempt to
evaluate this IO
without first yielding to the event loop.
Attributes
- See also:
- Inherited from:
- IOPlatform (hidden)
- Source:
- IOPlatform.scala
Evaluates the effect and produces the result in a JavaScript Promise
.
Evaluates the effect and produces the result in a JavaScript Promise
.
This is similar to unsafeToPromise
in that it evaluates the IO
as a side effect in a
non-blocking fashion, but begins by taking a syncStep
limited by the runtime's auto-yield
threshold. This function should really only be used if it is critical to attempt to
evaluate this IO
without first yielding to the event loop.
Attributes
- See also:
- Inherited from:
- IOPlatform (hidden)
- Source:
- IOPlatform.scala
Evaluates the effect and produces the result in a JavaScript Promise
.
Evaluates the effect and produces the result in a JavaScript Promise
.
This is similar to unsafeRunAsync
in that it evaluates the IO
as a side effect in a
non-blocking fashion, but uses a Promise
rather than an explicit callback. This function
should really only be used if interoperating with code which uses JavaScript promises.
Attributes
- See also:
- Inherited from:
- IOPlatform (hidden)
- Source:
- IOPlatform.scala