A purely functional data structure that describes a process. This process
may evaluate actions in an effect type F, emit any number of output values
of type O (or None), and may a) terminate with a single result of type R;
or b) terminate abnormally by raising (inside the effect F
) an exception,
or c) terminate because it was cancelled by another process,
or d) not terminate.
Like types from other effect libraries, pulls are pure and immutable values. They preserve referential transparency.
=== Chunking ===
The output values of a pull are emitted not one by one, but in chunks.
A Chunk
is an immutable sequence with constant-time indexed lookup. For example,
a pull p: Pull[F, Byte, R]
internally operates and emits Chunk[Byte]
values, which can wrap unboxed byte arrays -- avoiding boxing/unboxing costs.
The Pull
API provides mechanisms for working at both the chunk level and
the individual element level. Generally, working at the chunk level will
result in better performance but at the cost of more complex implementations
A pull only emits non-empty chunks.
However, chunks are not merely an operational matter of efficiency. Each pull is emitted from a chunk atomically, which is to say, any errors or interruptions in a pull can only happen between chunks, not within a chunk. For instance, if creating a new chunk of values fails (raises an uncaught exception) while creating an intermediate value, then it fails to create the entire chunk and previous values are discarded.
=== Evaluation ===
Like other functional effect types (e.g. cats.effect.IO
), a pull
describes a process or computation. It is not a running process nor a
handle for the result of a spawned, running process, like scala.concurrent.Future
.
A pull can be converted to a stream and then compiled to an effectful value.
For a Pull[F, O, Unit]
, the result of compilation is a combination, via the
monad instance of F
, of all the actions in the effect F
present in the pull.
The result of that F
action is the result of combining the outputs emitted by
the pull, in the order it emits them, using a fold function. Depending on that
function, outputs may be collected into a list (or vector or array or ...),
combined together into a single value, or just discarded altogether (by draining
the pull).
Compilation is pull-based, rather than push-based (hence the name of the datatype). It is the compilation process itself, that determines when the evaluation of each single effect can proceed or is held back. Effects and outputs later in the pull are not performed or emitted, unless and until the compilation calls for them.
=== Resource scoping ===
The effects in a Pull
may operate on resources, which must be retained during
the execution of the pull, may be shared by several pulls, and must be
properly finalised when no longer needed, regardless of whether the pull completed
successfully or not. A pull tracks its resources using '''scopes''', which register
how many pulls are actively using each resource, and finalises resources when no
longer used.
Some operations of the Pull
API can be used to introduce new resource scopes,
or resource boundaries.
=== Functional typeclasses ===
The Pull
data structure is a "free" implementation of Monad
and has an instance
for cats.effect.kernel.Sync
.
For any types F[_]
and O
, a Pull[F, O, *]
holds the following laws:
pure >=> f == f
f >=> pure == f
(f >=> g) >=> h == f >=> (g >=> h)
wheref >=> g
is defined asa => a flatMap f flatMap g
handleErrorWith(raiseError(e))(f) == f(e)
Attributes
- F[_]
the type of effect that can be performed by this pull. An effect type of
Nothing
, also known infs2
by the aliasPure
, indicates that this pull perform no effectful actions. Note:Nothing
is a polykinded type, so it can also be applied as an argument to the type parameterF[_]
.- O
The outputs emitted by this Pull. An output type of
Nothing
means that this pull does not emit any outputs.- R
The type of result returned by this Pull upon successful termination. An output type of
Nothing
indicates that this pull cannot terminate successfully: it may fail, be cancelled, or never terminate.- Companion:
- object
- Source:
- Pull.scala
- Graph
- Supertypes
- class Objecttrait Matchableclass Any