Fold

h8io.stages.cycles.Fold
See theFold companion object
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], Fruitful[(R, I), R, E]

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 R via the binary operation stage op.

Unlike Reduce, the accumulator is never empty: apply receives the seed R alongside the input, so every output the inner stage produces — including the first — is folded via op((accumulator, output)); there is no seedless first output to special-case. Because the accumulator always has a value to yield, Fold mixes in h8io.stages.base.Fruitful: apply is statically guaranteed to return h8io.stages.Yield.Some.

That guarantee shapes what happens when op itself produces no output for a given fold (e.g. it filters some outputs out): the accumulator is left unchanged rather than discarded. Reduce can thread an unfolded value onward as None, since its accumulator is optional to begin with; Fold cannot — a Fruitful stage has no None to 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, since op was applied (not skipped) for that output. When the inner stage itself produces no output, op is skipped instead — as in Reduce — and only the inner stage's status carries the iteration, so each iteration still performs exactly one of apply/skip on 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 is h8io.stages.Status.Success, like Repeat. The cycle is @tailrec and does not grow the stack.

The cycle stops when the status of an iteration is h8io.stages.Status.Complete: an error-free Complete is reported to the enclosing pipeline as Success, a Complete with errors is preserved. The accumulator as it stands at that point is yielded. The accumulator is local to one outer run: the next generation of Fold starts fresh from whatever seed the next outer input supplies.

==The inner pipeline==

alterand and op together form the inner pipeline of Fold, with op downstream of alterand. An iteration's status is therefore the combination of their statuses in pipeline order (alterand first), and both continuations are selected by that combined status — exactly as h8io.stages.Evolution.AndThen evolves 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 Fold reports to the enclosing pipeline — the two differ, since an error-free Complete is absorbed into a Success — and for the same reason the returned evolution is a h8io.stages.base.ConstEvolution. Its dispose releases both inner evolutions via h8io.stages.Evolution.dispose (op first, then alterand), which per the h8io.stages.Evolution contract stay the terminal cleanup handles of the generation just constructed. Symmetrically a skipped Fold skips both inner stages and selects their continuations on the neutral Status.Success.

Type parameters

E

the error type (covariant)

I

the input type (contravariant)

O

the value type produced by alterand and consumed alongside the accumulator by op (invariant)

R

the accumulator type (invariant: seeded via the outer input, threaded as both input and output of op)

Value parameters

alterand

the inner stage whose outputs are folded

op

the binary operation stage folding the accumulator and an output into the next accumulator

Attributes

Companion
object
Graph
Supertypes
trait Serializable
trait Product
trait Equals
trait Fruitful[(R, I), R, E]
trait Alterator[Stage[I, O, E], (R, I), R, E]
trait Stage[(R, I), R, E]
trait ((R, I)) => Yield[(R, I), R, E]
class Object
trait Matchable
class Any
Show all

Members list

Value members

Concrete methods

override def apply(in: (R, I)): Some[(R, I), R, E]

Processes in and returns the Yield carrying the optional output, the status and the continuation.

Processes in and returns the Yield carrying the optional output, the status and the continuation.

A stage that throws from here must have released its own resources first — see the ''Lifecycle'' section above.

Attributes

Definition Classes
Fruitful -> Stage -> Function1
override def skip(): Evolution[(R, I), R, E]

Returns this stage's Evolution without consuming an input.

Returns this stage's Evolution without consuming an input.

Called instead of apply whenever the stage takes part in a run but has nothing to process: the upstream yielded no output, or a binary operator excluded this branch. The evolution must be the one the stage would have returned had it run. Like apply, skip() may perform side effects — a decorator, for instance, may advance or release the inner stage it owns.

Attributes

Definition Classes

Inherited methods

def andThen[A](g: Yield[(R, I), R, E] => A): (R, I) => A

Composes two instances of Function1 in a new Function1, with this function applied first.

Composes two instances of Function1 in a new Function1, with this function applied first.

Type parameters

A

the result type of function g

Value parameters

g

a function R => A

Attributes

Returns

a new function f such that f(x) == g(apply(x))

Inherited from:
Function1
def compose[A](g: A => (R, I)): A => Yield[(R, I), R, E]

Composes two instances of Function1 in a new Function1, with this function applied last.

Composes two instances of Function1 in a new Function1, with this function applied last.

Type parameters

A

the type to which function g can be applied

Value parameters

g

a function A => T1

Attributes

Returns

a new function f such that f(x) == apply(g(x))

Inherited from:
Function1
def productElementNames: Iterator[String]

An iterator over the names of all the elements of this product.

An iterator over the names of all the elements of this product.

Attributes

Inherited from:
Product
def productIterator: Iterator[Any]

An iterator over all the elements of this product.

An iterator over all the elements of this product.

Attributes

Returns

in the default implementation, an Iterator[Any]

Inherited from:
Product
override def toString(): String

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
Function1 -> Any
Inherited from:
Function1
final def ~>[_O, _E >: E](that: Stage[R, _O, _E]): Stage[(R, I), _O, _E]

Composes this stage with that, feeding this stage's output into it. See the ''Composition'' section above for what happens when there is no output to feed.

Composes this stage with that, feeding this stage's output into it. See the ''Composition'' section above for what happens when there is no output to feed.

Attributes

Inherited from:
Stage