Alterator
Alterator is the base trait for stages that wrap a single inner stage — the alterand. It declares the
abstract alterand member. Resource disposal stays with the Evolutions returned by apply and skip: a
concrete alterator must make sure its evolution delegates dispose to the alterand's evolution.
The type parameter S is covariant and bounded to Stage.Any, preserving the concrete type of the alterand in the
wrapper's static type without information loss.
Do not mix Alterator with traits that supply the stage's own continuation — its skip, evolve or dispose,
as SAMStage and Stagnation do. An alterator's evolution has to be built from the
alterand's; a mixin that answers this instead — and both of those seal it that way — leaves the alterand neither
evolved nor disposed, and nothing signals it.
Traits that only shape apply are safe to mix in, because they leave the continuation to the alterator itself.
SafeStage and Fruitful are both used that way in this library, by
Safe and Lift respectively.
The base package provides four type aliases for wrapping stages. The first two name the wrapper itself and are
built on Alterator; the other two name the function that produces one:
| Alias | Meaning |
|---|---|
UnaryOperator[+S, -I, +O, +E] |
Wraps any Stage[I, ?, ?]; may change all three type parameters |
Decorator[-I, +O, +E] |
Wraps a Stage[I, O, E] and preserves its full type |
Alteration[-IS, +OS] |
A function IS => OS that transforms one stage type into another |
Decoration[I, O, E] |
An Alteration[Stage[I, O, E], Stage[I, O, E]] — the shape passed to Evolution.map |
Decorator is the alias to reach for when building middleware that wraps a stage without changing its interface:
import h8io.stages.*
import h8io.stages.base.*
class Logged[I, O, E](val alterand: Stage[I, O, E]) extends Decorator[I, O, E] {
override def apply(in: I): Yield[I, O, E] = {
println(s"apply($in)")
alterand(in)
}
override def skip(): Evolution[I, O, E] = alterand.skip()
}
val logged = new Logged(DoubleInt)
// logged: Logged[Int, Int, Nothing] = <function1>
logged(10)
// apply(10)
// res0: Yield[Int, Int, Nothing] = Some(
// out = 20,
// status = Success,
// evolution = <function1>
// )
logged.skip()
// res1: Evolution[Int, Int, Nothing] = <function1>
Alteration and Decoration are the shapes used when passing stage transformations as values — for example, to
Evolution.map.