package cycles
- Alphabetic
- Public
- All
Type Members
-
final
case class
Fold[R, -I, O, +E](alterand: Stage[I, O, E], op: Stage[(R, O), R, E]) extends Alterator[Stage[I, O, E], (R, I), R, E] with Fruitful[(R, I), R, E] with Product with Serializable
A decorator that drives a whole cycle of the inner stage per outer run — like Repeat and Reduce, on the same outer input — folding every output the inner stage produces into an accumulator
Rvia the binary operation stageop.A decorator that drives a whole cycle of the inner stage per outer run — like Repeat and Reduce, on the same outer input — folding every output the inner stage produces into an accumulator
Rvia the binary operation stageop.Unlike Reduce, the accumulator is never empty:
applyreceives the seedRalongside the input, so every output the inner stage produces — including the first — is folded viaop((accumulator, output)); there is no seedless first output to special-case. Because the accumulator always has a value to yield,Foldmixes inh8io.stages.base.Fruitful:applyis statically guaranteed to returnh8io.stages.Yield.Some.That guarantee shapes what happens when
opitself produces no output for a given fold (e.g. it filters some outputs out): the accumulator is left unchanged rather than discarded.Reducecan thread an unfolded value onward asNone, since its accumulator is optional to begin with;Foldcannot — aFruitfulstage has noNoneto fall back to — so keeping the previous accumulator is the only option that preserves the guarantee.op's status is still combined into the iteration's status in this case, sinceopwas applied (not skipped) for that output. When the inner stage itself produces no output,opis skipped instead — as inReduce— and only the inner stage's status carries the iteration, so each iteration still performs exactly one ofapply/skipon both inner stages, as the lifecycle contract requires. An iteration that leaves the accumulator unchanged keeps the cycle spinning as long as the combined status ish8io.stages.Status.Success, like Repeat. The cycle is@tailrecand does not grow the stack.The cycle stops when the status of an iteration is
h8io.stages.Status.Complete: an error-freeCompleteis reported to the enclosing pipeline asSuccess, aCompletewith errors is preserved. The accumulator as it stands at that point is yielded. The accumulator is local to one outer run: the next generation ofFoldstarts fresh from whatever seed the next outer input supplies.The inner pipeline
alterandandoptogether form the inner pipeline ofFold, withopdownstream ofalterand. An iteration's status is therefore the combination of their statuses in pipeline order (alterandfirst), and both continuations are selected by that combined status — exactly ash8io.stages.Evolution.AndThenevolves both sides of a composed pipeline with the status of the whole run, never with the stages' individual statuses.As in Loop and Repeat, the continuations are never selected by the status
Foldreports to the enclosing pipeline — the two differ, since an error-freeCompleteis absorbed into aSuccess— and for the same reason the returned evolution is ah8io.stages.base.ConstEvolution. Itsdisposereleases both inner evolutions viah8io.stages.Evolution.dispose(opfirst, thenalterand), which per theh8io.stages.Evolutioncontract stay the terminal cleanup handles of the generation just constructed. Symmetrically a skippedFoldskips both inner stages and selects their continuations on the neutralStatus.Success.- R
the accumulator type (invariant: seeded via the outer input, threaded as both input and output of
op)- I
the input type (contravariant)
- O
the value type produced by
alterandand consumed alongside the accumulator byop(invariant)- E
the error type (covariant)
- alterand
the inner stage whose outputs are folded
- op
the binary operation stage folding the accumulator and an output into the next accumulator
-
final
case class
Loop[T, +E](alterand: Endo[T, E]) extends Decorator[T, T, E] with Product with Serializable
A decorator that feeds the output of each successful step back as the input of the next, effectively looping the inner endomorphic stage until it stops.
A decorator that feeds the output of each successful step back as the input of the next, effectively looping the inner endomorphic stage until it stops.
The tail-recursive loop works as follows:
h8io.stages.Status.Success+h8io.stages.Yield.Some: the output becomes the new input and the loop continues with the stage selected byyld.evolve().h8io.stages.Status.Success+h8io.stages.Yield.None: no output was produced; the loop stops and emits aYield.NonewithSuccessstatus whose continuation is the stage selected byyld.evolve(), wrapped back inLoop.h8io.stages.Status.Completewith no errors: the loop stops, converts the status back toSuccess, and wraps the stage selected byyld.evolve()inLoopfor the next outer invocation.h8io.stages.Status.Completewith errors: the loop stops, preserves the errors, and selects the continuation the same way.
In every branch the continuation of the inner stage is selected by the status the inner stage itself produced, and never by the status
Loopreports to the enclosing pipeline — the two differ, since an error-freeCompleteis absorbed into aSuccess. For the same reason the returned evolution is ah8io.stages.base.ConstEvolution: the status the enclosing pipeline evolvesLoopwith belongs to that pipeline, not to the inner stage, and must not be passed inwards. Symmetrically, a skippedLoopskips its inner stage and selects the inner continuation on the neutralStatus.Success. The returnedConstEvolutionkeeps the inner evolution'sdisposeas its own: per theh8io.stages.Evolutioncontract, the inner evolution stays the terminal cleanup handle for the generation constructed here until that generation runs.This makes
Loopsuitable for in-process iterative computations (e.g., fixed-point iterations) where the result of one step seeds the next.- T
the value type (both input and output)
- E
the error type (covariant)
- alterand
the inner endomorphic stage
T → Tto loop
-
final
case class
Reduce[-I, O, +E](alterand: Stage[I, O, E], op: Stage[(O, O), O, E]) extends Decorator[I, O, E] with Product with Serializable
A decorator that drives a whole cycle of the inner stage per outer run — like Repeat, on the same outer input — folding every output the inner stage produces into an accumulator with the binary operation stage
op.A decorator that drives a whole cycle of the inner stage per outer run — like Repeat, on the same outer input — folding every output the inner stage produces into an accumulator with the binary operation stage
op.The first output becomes the accumulator without invoking
op(the classic seedless reduce); each subsequent output is folded viaop((accumulator, output)). In an iteration with nothing to fold — the inner stage produced no output, or the output is the first one —opis skipped, so each iteration performs exactly one ofapply/skipon both inner stages, as the lifecycle contract requires. An iteration yielding no output withh8io.stages.Status.Successkeeps the cycle spinning, like Repeat. The cycle is@tailrecand does not grow the stack.When
opis applied but itself yields no output for a given fold — e.g. it filters some outputs out — the accumulator is left unchanged rather than discarded, exactly as in Fold.op's status is still combined into the iteration's status in this case, sinceopwas applied, not skipped, for that output.The cycle stops when the status of an iteration is
h8io.stages.Status.Complete: an error-freeCompleteis reported to the enclosing pipeline asSuccess, aCompletewith errors is preserved. The value accumulated so far, if any, is yielded. The accumulator is local to one outer run: the next generation ofReducestarts empty.The inner pipeline
alterandandoptogether form the inner pipeline ofReduce, withopdownstream ofalterand. An iteration's status is therefore the combination of their statuses in pipeline order (alterandfirst), and both continuations are selected by that combined status — exactly ash8io.stages.Evolution.AndThenevolves both sides of a composed pipeline with the status of the whole run, never with the stages' individual statuses.As in Loop and Repeat, the continuations are never selected by the status
Reducereports to the enclosing pipeline — the two differ, since an error-freeCompleteis absorbed into aSuccess— and for the same reason the returned evolution is ah8io.stages.base.ConstEvolution. Itsdisposereleases both inner evolutions viah8io.stages.Evolution.dispose(opfirst, thenalterand), which per theh8io.stages.Evolutioncontract stay the terminal cleanup handles of the generation just constructed. Symmetrically a skippedReduceskips both inner stages and selects their continuations on the neutralStatus.Success.- I
the input type (contravariant)
- O
the value type being reduced (invariant: produced by
alterand, consumed in pairs byop)- E
the error type (covariant)
- alterand
the inner stage whose outputs are reduced
- op
the binary operation stage folding two values into one
-
final
case class
Repeat[-I, +O, +E](alterand: Stage[I, O, E]) extends Decorator[I, O, E] with Product with Serializable
A decorator that keeps re-applying the inner stage (following the continuations its
h8io.stages.Evolutionselects forh8io.stages.Status.Success) until the stage signals completion or an error.A decorator that keeps re-applying the inner stage (following the continuations its
h8io.stages.Evolutionselects forh8io.stages.Status.Success) until the stage signals completion or an error.The loop is implemented with
@tailrecso it does not grow the stack. The loop continues as long as the inner stage yieldsh8io.stages.Status.Success. It stops onh8io.stages.Status.Complete: if there are no errors the status is converted back toSuccess; if there are errors, theCompletestatus is preserved.In every branch the continuation of the inner stage is selected by the status the inner stage itself produced, and never by the status
Repeatreports to the enclosing pipeline — the two differ, since an error-freeCompleteis absorbed into aSuccess. For the same reason the returned evolution is ah8io.stages.base.ConstEvolution: the status the enclosing pipeline evolvesRepeatwith belongs to that pipeline, not to the inner stage, and must not be passed inwards. Symmetrically, a skippedRepeatskips its inner stage and selects the inner continuation on the neutralStatus.Success. The returnedConstEvolutionkeeps the inner evolution'sdisposeas its own: per theh8io.stages.Evolutioncontract, the inner evolution stays the terminal cleanup handle for the generation constructed here until that generation runs.Repeatis useful for driving stages like h8io.stages.std.Countdown that signal "batch complete" viaStatus.Completeand should be repeated as a whole unit.- I
the input type (contravariant)
- O
the output type (covariant)
- E
the error type (covariant)
- alterand
the inner stage to repeat