FruitfulStaticStage

FruitfulStaticStage is the fruitful counterpart of StaticStage: a stage that is its own evolution and always produces an output value. apply and skip are sealed; the single abstract method is process(in: I): (O, Status[E]) — the output value paired with its status, no yield wrapping at all.

apply carries the Yield.Some return type required by Fruitful, so the always-an-output guarantee is tracked statically.

import h8io.stages.*
import h8io.stages.base.*
object ClampNonNegative extends FruitfulStaticStage[Int, Int, String] {
  override protected def process(in: Int): (Int, Status[String]) =
    if (in >= 0) (in, Status.Success) else (0, Status.error(s"negative input: $in"))
}

ClampNonNegative(7)
// res0: Yield.Some[Int, Int, String] = Some(
//   out = 7,
//   status = Success,
//   evolution = <function1>
// )
ClampNonNegative(-3)
// res1: Yield.Some[Int, Int, String] = Some(
//   out = 0,
//   status = Complete("negative input: -3"),
//   evolution = <function1>
// )

Use FruitfulStaticStage when the stage always has a value to return but the status may vary — for example Complete, GlobalSoftDeadline, and the Tuple2 projections. When the status is always Success as well, Fn is more specific; when output is not always produced, use StaticStage.