A Chunk[A]
represents a chunk of values of type A
.
A Chunk[A]
represents a chunk of values of type A
. Chunks are designed
are usually backed by arrays, but expose a purely functional, safe interface
to the underlying elements, and they become lazy on operations that would be
costly with arrays, such as repeated concatenation.
An Exit[E, A]
describes the result of executing an IO
value.
An Exit[E, A]
describes the result of executing an IO
value. The
result is either succeeded with a value A
, or failed with a Cause[E]
.
A fiber is a lightweight thread of execution that never consumes more than a whole thread (but may consume much less, depending on contention).
A fiber is a lightweight thread of execution that never consumes more than a
whole thread (but may consume much less, depending on contention). Fibers are
spawned by forking IO
actions, which, conceptually at least, runs them
concurrently with the parent IO
action.
Fibers can be joined, yielding their result other fibers, or interrupted, which terminates the fiber with a runtime error.
Fork-Join Identity: fork >=> join = id
for { fiber1 <- io1.fork fiber2 <- io2.fork _ <- fiber1.interrupt(e) a <- fiber2.join } yield a
Represents a failure in a fiber.
Represents a failure in a fiber. This could be caused by some non- recoverable error, such as a defect or system error, by some typed error, or by interruption (or combinations of all of the above).
This class is used to wrap ZIO failures into something that can be thrown, to better integrate with Scala exception handling.
A container for fiber-local storage.
A container for fiber-local storage. It is the pure equivalent to Java's ThreadLocal
on a fiber architecture.
Fiber's counterpart for Java's ThreadLocal
.
Fiber's counterpart for Java's ThreadLocal
. Value is automatically propagated
to child on fork and merged back in after joining child.
for { fiberRef <- FiberRef.make("Hello world!") child <- fiberRef.set("Hi!).fork result <- child.join } yield result
result
will be equal to "Hi!" as changes done by child were merged on join.
A FunctionIO[E, A, B]
is an effectful function from A
to B
, which might
fail with an E
.
A FunctionIO[E, A, B]
is an effectful function from A
to B
, which might
fail with an E
.
This is the moral equivalent of A => IO[E, B]
, and, indeed, FunctionIO
extends this function type, and can be used in the same way.
The main advantage to using FunctionIO
is that it provides you a means of
importing an impure function A => B
into FunctionIO[E, A, B]
, without
actually wrapping the result of the function in an IO
value.
This allows the implementation to aggressively fuse operations on impure
functions, which in turn can result in significantly higher-performance and
far less heap utilization than equivalent approaches modeled with IO
.
The implementation allows you to lift functions from A => IO[E, B]
into a
FunctionIO[E, A, B]
. Such functions cannot be optimized, but will be handled
correctly and can work in conjunction with optimized (fused) FunctionIO
.
Those interested in learning more about modeling effects with FunctionIO
are
encouraged to read John Hughes paper on the subject: Generalizing Monads to
Arrows (www.cse.chalmers.se/~rjmh/Papers/arrows.pdf). The implementation in
this file contains many of the same combinators as Hughes implementation.
A word of warning: while even very complex code can be expressed in
FunctionIO
, there is a point of diminishing return. If you find yourself
using deeply nested tuples to propagate information forward, it may be no
faster than using IO
.
Given the following two FunctionIO
:
val readLine = FunctionIO.impureVoid((_ : Unit) => scala.Console.readLine()) val printLine = FunctionIO.impureVoid((line: String) => println(line))
Then the following two programs are equivalent:
// Program 1 val program1: UIO[Unit] = for { name <- getStrLn _ <- putStrLn("Hello, " + name) } yield ()) // Program 2 val program2: UIO[Unit] = (readLine >>> FunctionIO.fromFunction("Hello, " + _) >>> printLine)(())
Similarly, the following two programs are equivalent:
// Program 1 val program1: UIO[Unit] = for { line1 <- getStrLn line2 <- getStrLn _ <- putStrLn("You wrote: " + line1 + ", " + line2) } yield ()) // Program 2 val program2: UIO[Unit] = (readLine.zipWith(readLine)("You wrote: " + _ + ", " + _) >>> printLine)(())
In both of these examples, the FunctionIO
program is faster because it is
able to perform fusion of effectful functions.
The InterruptStatus
of a fiber determines whether or not it can be
interrupted.
The InterruptStatus
of a fiber determines whether or not it can be
interrupted. The status can change over time in different regions.
A promise represents an asynchronous variable that can be set exactly once,
with the ability for an arbitrary number of fibers to suspend (by calling
get
) and automatically resume when the variable is set.
A promise represents an asynchronous variable that can be set exactly once,
with the ability for an arbitrary number of fibers to suspend (by calling
get
) and automatically resume when the variable is set.
Promises can be used for building primitive actions whose completions require the coordinated action of multiple fibers, and for building higher-level concurrent or asynchronous structures.
for { promise <- Promise.make[Nothing, Int] _ <- promise.complete(42).delay(1.second).fork value <- promise.get // Resumes when forked fiber completes promise } yield value
A mutable atomic reference for the IO
monad.
A mutable atomic reference for the IO
monad. This is the IO
equivalent of
a volatile var
, augmented with atomic operations, which make it useful as a
reasonably efficient (if low-level) concurrency primitive.
for { ref <- Ref.make(2) v <- ref.update(_ + 3) _ <- console.putStrLn("Value = " + v) // Value = 5 } yield ()
A mutable atomic reference for the IO
monad.
A mutable atomic reference for the IO
monad. This is the IO
equivalent of
a volatile var
, augmented with atomic effectful operations, which make it
useful as a reasonably efficient (if low-level) concurrency primitive.
Unlike Ref
, RefM
allows effects in atomic operations, which makes the
structure slower but more powerful than Ref
.
for { ref <- RefM(2) v <- ref.update(_ + putStrLn("Hello World!").attempt.unit *> IO.succeed(3)) _ <- putStrLn("Value = " + v) // Value = 5 } yield ()
A Reservation[-R, +E, +A]
encapsulates resource aquisition and disposal
without specifying when or how that resource might be used.
A Reservation[-R, +E, +A]
encapsulates resource aquisition and disposal
without specifying when or how that resource might be used.
See ZManaged#reserve and ZIO#reserve for details of usage.
A Runtime[R]
is capable of executing tasks within an environment R
.
An asynchronous semaphore, which is a generalization of a mutex.
An asynchronous semaphore, which is a generalization of a mutex. Semaphores have a certain number of permits, which can be held and released concurrently by different parties. Attempts to acquire more permits than available result in the acquiring fiber being suspended until the specified number of permits become available.
Whether ZIO Tracing is enabled for the current fiber in the current region.
A ZIO[R, E, A]
("Zee-Oh of Are Eeh Aye") is an immutable data structure
that models an effectful program.
A ZIO[R, E, A]
("Zee-Oh of Are Eeh Aye") is an immutable data structure
that models an effectful program. The effect requires an environment R
,
and the effect may fail with an error E
or produce a single A
.
Conceptually, this structure is equivalent to ReaderT[R, EitherT[UIO, E, ?]]
for some infallible effect monad UIO
, but because monad transformers
perform poorly in Scala, this data structure bakes in the reader effect of
ReaderT
with the recoverable error effect of EitherT
without runtime
overhead.
ZIO
values are ordinary immutable values, and may be used like any other
value in purely functional code. Because ZIO
values just *model* effects
(like input / output), which must be interpreted by a separate runtime system,
ZIO
values are entirely pure and do not violate referential transparency.
ZIO
values can efficiently describe the following classes of effects:
ZIO.succeed
Error Effects
— ZIO.fail
IO.effect
IO.effectAsync
IO#fork
IO#bracket
Contextual Effects
— ZIO.access
The concurrency model is based on fibers, a user-land lightweight thread, which permit cooperative multitasking, fine-grained interruption, and very high performance with large numbers of concurrently executing fibers.
ZIO
values compose with other ZIO
values in a variety of ways to build
complex, rich, interactive applications. See the methods on ZIO
for more
details about how to compose ZIO
values.
In order to integrate with Scala, ZIO
values must be interpreted into the
Scala runtime. This process of interpretation executes the effects described
by a given immutable ZIO
value. For more information on interpreting ZIO
values, see the default interpreter in DefaultRuntime
or the safe main function in
App
.
A ZManaged[R, E, A]
is a managed resource of type A
, which may be used by
invoking the use
method of the resource.
A ZManaged[R, E, A]
is a managed resource of type A
, which may be used by
invoking the use
method of the resource. The resource will be automatically
acquired before the resource is used, and automatically released after the
resource is used.
Resources do not survive the scope of use
, meaning that if you attempt to
capture the resource, leak it from use
, and then use it after the resource
has been consumed, the resource will not be valid anymore and may fail with
some checked error, as per the type of the functions provided by the resource.
A ZQueue[RA, EA, RB, EB, A, B]
is a lightweight, asynchronous queue into which values of
type A
can be enqueued and of which elements of type B
can be dequeued.
A ZQueue[RA, EA, RB, EB, A, B]
is a lightweight, asynchronous queue into which values of
type A
can be enqueued and of which elements of type B
can be dequeued. The queue's
enqueueing operations may utilize an environment of type RA
and may fail with errors of
type EA
. The dequeueing operations may utilize an environment of type RB
and may fail
with errors of type EB
.
Defines a stateful, possibly effectful, recurring schedule of actions.
Defines a stateful, possibly effectful, recurring schedule of actions.
A ZSchedule[R, A, B]
consumes A
values, and based on the inputs and the
internal state, decides whether to continue or halt. Every decision is
accompanied by a (possibly zero) delay, and an output value of type B
.
Schedules compose in each of the following ways:
1. Intersection, using the &&
operator, which requires that both schedules
continue, using the longer of the two durations.
2. Union, using the ||
operator, which requires that only one schedule
continues, using the shorter of the two durations.
3. Sequence, using the <||>
operator, which runs the first schedule until
it ends, and then switches over to the second schedule.
Schedule[R, A, B]
forms a profunctor on [A, B]
, an applicative functor on
B
, and a monoid, allowing rich composition of different schedules.
This object was generated by sbt-buildinfo.