Evolution

h8io.stages.base.`package`.BaseBinaryOperator.Evolution
trait Evolution[-I, LO, RO, +O, +E] extends Evolution[I, O, E]

The continuation of a BaseBinaryOperator: a pair of sub-evolutions that evolve and dispose together.

Concrete operators implement apply alone — the reassembly of the two continuations into the operator's own shape — and inherit the two halves of the shared contract:

  • evolve selects both continuations on the same status, the right one first, and hands them to apply;
  • dispose releases both through h8io.stages.Evolution.dispose, right first, so that a failure of one still leaves the other released and is reported as suppressed.

Type parameters

E

the shared error type (covariant)

I

the shared input type (contravariant)

LO

the left output type (invariant: consumed and produced by the sub-evolution)

O

the combined output type (covariant)

RO

the right output type (invariant, likewise)

Attributes

Graph
Supertypes
trait Evolution[I, O, E]
class Object
trait Matchable
class Any

Members list

Value members

Abstract methods

protected def apply[_I <: I, _E >: E](leftStage: Stage[_I, LO, _E], rightStage: Stage[_I, RO, _E]): Stage[_I, O, _E]

Rebuilds the operator from the two continuations — normally the operator's own constructor.

Rebuilds the operator from the two continuations — normally the operator's own constructor.

Value parameters

leftStage

the stage the left sub-evolution selected

rightStage

the stage the right sub-evolution selected

Attributes

def left: Evolution[I, LO, E]

The continuation of the left sub-stage.

The continuation of the left sub-stage.

Attributes

def right: Evolution[I, RO, E]

The continuation of the right sub-stage.

The continuation of the right sub-stage.

Attributes

Concrete methods

override def dispose(): Unit

Releases everything held by the Stage that produced this evolution. That stage is permanently unusable afterwards — neither applied nor skipped again — and this is the only place its resources are released.

Releases everything held by the Stage that produced this evolution. That stage is permanently unusable afterwards — neither applied nor skipped again — and this is the only place its resources are released.

Whoever terminates a pipeline is responsible for disposing the evolution of the final Yield, so that the continuation is released at once instead of being carried around. The reference terminal driver is the execute extension method of h8io.stages.base in the lib module.

dispose() stays valid after evolve has been called on the same instance, and must then release everything still alive, including whatever building the continuation acquired. evolve hands over no ownership: this evolution remains the cleanup point for its lineage until the continuation has run and produced an evolution of its own, which takes the role over from that moment.

Exceptions are not part of this contract: a stage whose apply throws produces no yield and therefore no evolution, so there is nothing to dispose — it must clean up after itself (see the ''Lifecycle'' section in Stage).

A no-op is a fine implementation for a stage holding nothing external.

Attributes

Definition Classes
override def evolve(status: Status[_]): Stage[I, O, E]

The next stage, for the given status.

The next stage, for the given status.

May release what belongs to this generation alone — anything the returned stage and its own evolution will not reuse.

evolve and dispose are not mutually exclusive. Usually only one of them is called on an instance: a terminal driver disposes, a continuing pipeline evolves and drops the previous evolution. But a caller may do both, and operators owning their inner stage (Loop, Repeat and the rest of h8io.stages.cycles in the lib module) do exactly that — they evolve eagerly and keep the inner dispose as the cleanup handle of the generation they just built.

Attributes

Definition Classes

Inherited methods

final def compose[_O, _E >: E](that: Evolution[O, _O, _E]): Evolution[I, _O, _E]

Composes this evolution with the one downstream of it, so that for every status

Composes this evolution with the one downstream of it, so that for every status

 composed(s) == self(s) ~> that(s)

This is how Yield composition carries both continuations of a pipeline forward; application code rarely calls it directly.

Attributes

Inherited from:
Evolution
final def map[_I, _O, _E](f: Stage[I, O, E] => Stage[_I, _O, _E]): Evolution[_I, _O, _E]

Applies f to every stage this evolution would return, leaving disposal delegated to it unchanged.

Applies f to every stage this evolution would return, leaving disposal delegated to it unchanged.

The way an operator keeps its wrapping in place across generations: the continuation comes back wrapped the same way the current stage is.

Attributes

Inherited from:
Evolution