Repeat
Repeat keeps re-applying the inner stage to the same input, following Status.Success
transitions, until the stage signals completion. On an error-free Status.Complete
the status is converted back to Success; if the Complete carries errors, those are preserved.
Only the status ends the cycle. An iteration that yields Yield.None with Success
keeps Repeat spinning — deliberately so: unlike Loop, Repeat never feeds an output anywhere, so the
absence of one says nothing about whether the work is done. A stage that has to stop the cycle without producing a
value must say so with Complete.
As in Loop, the continuation of the inner stage is selected on the status the inner stage itself
produced — never on the status Repeat reports to the enclosing pipeline (an error-free Complete is absorbed into a
Success), and never on the status that pipeline later evolves Repeat with. A skipped Repeat skips its inner stage
and selects the inner continuation on the neutral Success.
Unlike Loop, Repeat does not feed output back as input — the same original input is passed on
every iteration. It is suited for stages like Countdown that batch a fixed number of
runs and signal Complete at the end of each batch.
import h8io.stages.*
import h8io.stages.std.*
import h8io.stages.cycles.*
Repeat(Countdown[String](3))("x")
// res0: Yield[String, String, Nothing] = Some(
// out = "x",
// status = Success,
// evolution = ConstEvolution(
// stage = Repeat(alterand = Countdown(i = 3L, n = 3L)),
// _dispose = h8io.stages.cycles.Repeat$$Lambda$19878/0x00007f58029acb68@2e771880
// )
// )
Countdown(3) processes "x" three times: Success, Success, Complete. Repeat absorbs the Complete
and returns Some("x", Success, Repeat(Countdown(3))), ready for the next invocation.