A single processing unit of a pipeline: a function from an input value to a Yield — an optional output, a Status, and an Evolution that decides what the pipeline looks like for the next run.
==Lifecycle==
Every stage instance takes exactly one of three paths per pipeline run:
- '''applied''' — apply receives an input value and returns a Yield. It may perform side effects and produce any output, status and evolution it likes.
- '''skipped''' — skip returns the evolution the stage would have returned had it run, without consuming an input. Any stage that takes part in a run but does not process the current input takes this path.
- '''failed''' —
applythrows. NoYield, and therefore noEvolution, reaches the caller.
Resource cleanup belongs to the Evolution returned by either of the first two: Evolution.dispose is the exclusive release point, and the stage is permanently unusable afterwards. The failed path is the one case where nobody outside can release anything — there is no evolution to dispose — so a stage that throws must release its own resources before letting the exception escape. The core takes no other part in exception handling; the lib module offers h8io.stages.operators.Safe as a crutch for the simplest, stateless cases. Fatal exceptions are outside this contract.
==Composition==
~> builds a pipeline out of two stages. When the upstream yields an output, it becomes the downstream's input and the two yields are merged; when it yields nothing, the downstream is not applied for this input — it is skipped and its evolution composed in, so it still evolves in step with the rest of the pipeline.
Type parameters
- E
-
the error type (covariant)
- I
-
the input type (contravariant)
- O
-
the output type (covariant)