Packages

p

cats

effect

package effect

Ordering
  1. Alphabetic
Visibility
  1. Public
  2. All

Type Members

  1. trait Async[F[_]] extends Sync[F] with LiftIO[F] with Serializable

    A monad that can describe asynchronous or synchronous computations that produce exactly one result.

    A monad that can describe asynchronous or synchronous computations that produce exactly one result.

    On Asynchrony

    An asynchronous task represents logic that executes independent of the main program flow, or current callstack. It can be a task whose result gets computed on another thread, or on some other machine on the network.

    In terms of types, normally asynchronous processes are represented as:

    (A => Unit) => Unit

    This signature can be recognized in the "Observer pattern" described in the "Gang of Four", although it should be noted that without an onComplete event (like in the Rx Observable pattern) you can't detect completion in case this callback can be called zero or multiple times.

    Some abstractions allow for signaling an error condition (e.g. MonadError data types), so this would be a signature that's closer to Scala's Future#onComplete:

    (Either[Throwable, A] => Unit) => Unit

    And many times the abstractions built to deal with asynchronous tasks also provide a way to cancel such processes, to be used in race conditions in order to cleanup resources early:

    (A => Unit) => Cancelable

    This is approximately the signature of JavaScript's setTimeout, which will return a "task ID" that can be used to cancel it.

    N.B. this type class in particular is NOT describing cancelable async processes, see the Concurrent type class for that.

    Async Type class

    This type class allows the modeling of data types that:

    1. can start asynchronous processes
    2. can emit one result on completion
    3. can end in error

    N.B. on the "one result" signaling, this is not an exactly once requirement. At this point streaming types can implement Async and such an exactly once requirement is only clear in Effect.

    Therefore the signature exposed by the async builder is this:

    (Either[Throwable, A] => Unit) => Unit

    N.B. such asynchronous processes are not cancelable. See the Concurrent alternative for that.

    Annotations
    @implicitNotFound( ... )
  2. trait Bracket[F[_], E] extends MonadError[F, E]

    An extension of MonadError exposing the bracket operation, a generalized abstracted pattern of safe resource acquisition and release in the face of errors or interruption.

  3. trait Concurrent[F[_]] extends Async[F] with Serializable

    Type class for Async data types that are cancelable and can be started concurrently.

    Type class for Async data types that are cancelable and can be started concurrently.

    Thus this type class allows abstracting over data types that:

    1. implement the Async algebra, with all its restrictions
    2. can provide logic for cancelation, to be used in race conditions in order to release resources early (in its cancelable builder)

    Due to these restrictions, this type class also affords to describe a start operation that can start async processing, suspended in the context of F[_] and that can be cancelled or joined.

    Without cancelation being baked in, we couldn't afford to do it. See below.

    Cancelable builder

    The signature exposed by the cancelable builder is this:

    (Either[Throwable, A] => Unit) => F[Unit]

    F[Unit] is used to represent a cancelation action which will send a signal to the producer, that may observe it and cancel the asynchronous process.

    On Cancellation

    Simple asynchronous processes, like Scala's Future, can be described with this very basic and side-effectful type and you should recognize what is more or less the signature of Future#onComplete or of Async.async (minus the error handling):

    (A => Unit) => Unit

    But many times the abstractions built to deal with asynchronous tasks can also provide a way to cancel such processes, to be used in race conditions in order to cleanup resources early, so a very basic and side-effectful definition of asynchronous processes that can be cancelled would be:

    (A => Unit) => Cancelable

    This is approximately the signature of JavaScript's setTimeout, which will return a "task ID" that can be used to cancel it. Or of Java's ScheduledExecutorService#schedule, which will return a Java ScheduledFuture that has a .cancel() operation on it.

    Similarly, for Concurrent data types, we can provide cancelation logic, that can be triggered in race conditions to cancel the on-going processing, only that Concurrent's cancelable token is an action suspended in an IO[Unit]. See IO.cancelable.

    Suppose you want to describe a "sleep" operation, like that described by Timer to mirror Java's ScheduledExecutorService.schedule or JavaScript's setTimeout:

    def sleep(d: FiniteDuration): F[Unit]

    This signature is in fact incomplete for data types that are not cancelable, because such equivalent operations always return some cancelation token that can be used to trigger a forceful interruption of the timer. This is not a normal "dispose" or "finally" clause in a try/catch block, because "cancel" in the context of an asynchronous process is concurrent with the task's own run-loop.

    To understand what this means, consider that in the case of our sleep as described above, on cancelation we'd need a way to signal to the underlying ScheduledExecutorService to forcefully remove the scheduled Runnable from its internal queue of scheduled tasks, before its execution. Therefore, without a cancelable data type, a safe signature needs to return a cancelation token, so it would look like this:

    def sleep(d: FiniteDuration): F[(F[Unit], F[Unit])]

    This function is returning a tuple, with one F[Unit] to wait for the completion of our sleep and a second F[Unit] to cancel the scheduled computation in case we need it. This is in fact the shape of Fiber's API. And this is exactly what the start operation returns.

    The difference between a Concurrent data type and one that is only Async is that you can go from any F[A] to a F[Fiber[F, A]], to participate in race conditions and that can be cancelled should the need arise, in order to trigger an early release of allocated resources.

    Thus a Concurrent data type can safely participate in race conditions, whereas a data type that is only Async cannot do it without exposing and forcing the user to work with cancelation tokens. An Async data type cannot expose for example a start operation that is safe.

    Annotations
    @implicitNotFound( ... )
  4. trait ConcurrentEffect[F[_]] extends Concurrent[F] with Effect[F] with Serializable

    Type class describing effect data types that are cancelable.

    Type class describing effect data types that are cancelable.

    In addition to the algebras of Concurrent and of Effect, instances must also implement a runCancelable operation that triggers the evaluation, suspended in the IO context, but that also returns a token that can be used for cancelling the running computation.

    Note this is the safe and generic version of IO.unsafeRunCancelable.

    Annotations
    @implicitNotFound( ... )
  5. trait Effect[F[_]] extends Async[F] with Serializable

    A monad that can suspend side effects into the F context and that supports lazy and potentially asynchronous evaluation.

    A monad that can suspend side effects into the F context and that supports lazy and potentially asynchronous evaluation.

    This type class is describing data types that:

    1. implement the Async algebra
    2. implement a lawful runAsync operation that triggers the evaluation (in the context of IO)

    Note this is the safe and generic version of IO.unsafeRunAsync (aka Haskell's unsafePerformIO).

    Annotations
    @implicitNotFound( ... )
  6. sealed abstract class ExitCase[+E] extends Product with Serializable

    Type for signaling the exit condition of an effectful computation, that may either succeed, fail with an error or get canceled.

    Type for signaling the exit condition of an effectful computation, that may either succeed, fail with an error or get canceled.

    The types of exit signals are:

    • Completed: for successful completion (from the type of view of this MonadError)
    • Error: for termination in failure (via MonadError[F, E])
    • Canceled: for abortion
  7. trait Fiber[F[_], A] extends AnyRef

    Fiber represents the (pure) result of an Async data type (e.g.

    Fiber represents the (pure) result of an Async data type (e.g. IO) being started concurrently and that can be either joined or cancelled.

    You can think of fibers as being lightweight threads, a fiber being a concurrency primitive for doing cooperative multi-tasking.

    For example a Fiber value is the result of evaluating IO.start:

    val io = IO.shift *> IO(println("Hello!"))
    
    val fiber: IO[Fiber[IO, Unit]] = io.start

    Usage example:

    for {
      fiber <- IO.shift *> launchMissiles.start
      _ <- runToBunker.handleErrorWith { error =>
        // Retreat failed, cancel launch (maybe we should
        // have retreated to our bunker before the launch?)
        fiber.cancel *> IO.raiseError(error)
      }
      aftermath <- fiber.join
    } yield {
      aftermath
    }
  8. sealed abstract class IO[+A] extends IOBinaryCompat[A]

    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).

    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:

    1. 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 of MonadError)
    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(a + b).flatMap { b2 =>
        if (n > 0)
          fib(n - 1, b, b2)
        else
          IO.pure(b2)
      }
  9. trait LiftIO[F[_]] extends Serializable
    Annotations
    @implicitNotFound( ... )
  10. trait Sync[F[_]] extends Bracket[F, Throwable] with Serializable

    A monad that can suspend the execution of side effects in the F[_] context.

  11. trait Timer[F[_]] extends AnyRef

    Timer is a scheduler of tasks.

    Timer is a scheduler of tasks.

    This is the purely functional equivalent of:

    It provides:

    1. the ability to get the current time
    2. thread / call-stack shifting
    3. ability to delay the execution of a task with a specified time duration

    It does all of that in an F monadic context that can suspend side effects and is capable of asynchronous execution (e.g. IO).

    This is NOT a type class, as it does not have the coherence requirement.

    Annotations
    @implicitNotFound( ... )

Value Members

  1. object Async extends Serializable
  2. object Bracket extends Serializable
  3. object Concurrent extends Serializable
  4. object ConcurrentEffect extends Serializable
  5. object Effect extends Serializable
  6. object ExitCase extends Serializable
  7. object Fiber
  8. object IO extends IOInstances

  9. object LiftIO extends Serializable
  10. object Sync extends Serializable
  11. object Timer

Ungrouped