Loop

Loop feeds the output of each successful step back as the input of the next, running the inner endomorphic stage in a tail-recursive loop until it stops.

The loop terminates when:

Loop is suited for in-process iterative computations where each step seeds the next.

Whichever way the loop ends, the continuation of the inner stage is selected on the status the inner stage itself produced — never on the status Loop reports to the enclosing pipeline (an error-free Complete is absorbed into a Success), and never on the status that pipeline later evolves Loop with. A skipped Loop skips its inner stage and selects the inner continuation on the neutral Success.

import h8io.stages.*
import h8io.stages.base.*
import h8io.stages.cycles.*
object IncrUntil10 extends SAMStage[Int, Int, Nothing] {
  override def apply(in: Int): Yield[Int, Int, Nothing] =
    if (in < 10) Yield.Some(in + 1, Status.Success, this)
    else         Yield.Some(in, Status.complete, this)
}

Loop(IncrUntil10)(3)
// res0: Yield[Int, Int, Nothing] = Some(
//   out = 10,
//   status = Success,
//   evolution = ConstEvolution(
//     stage = Loop(alterand = <function1>),
//     _dispose = h8io.stages.cycles.Loop$$Lambda$19867/0x00007f58029a28b8@7954ac46
//   )
// )

The loop increments from 3 to 10, exits on Complete, and returns Some(10, Success, ...).