Skip to main content

Swap

Swap is a polymorphic singleton: a single Fn[(Any, Any), (Any, Any)] instance that swaps the two elements of a pair, always yielding Status.Success. Use Swap[L, R] to obtain a typed Fn[(L, R), (R, L)].

import h8io.stages.*
import h8io.stages.std.*
val stage = Swap[String, Int]
// stage: base.Fn[(String, Int), (Int, String)] = <function1>
stage(("a", 1))
// res0: Yield.Some[(String, Int), (Int, String), Nothing] = Some(
// out = (1, "a"),
// status = Success,
// evolution = <function1>
// )

Reduce and Fold both call their op in the "left" convention, op((accumulator, output)). Composing Swap[R, O] ~> op in front of an op written the other way around — (output, accumulator) — adapts it without needing a separate ReduceRight/FoldRight operator. For a non-commutative op this changes the result:

import h8io.stages.base.*
import h8io.stages.cycles.*

object Once extends SAMStage[Unit, Int, Nothing] {
override def apply(in: Unit): Yield[Unit, Int, Nothing] = Yield.Some(3, Status.complete, this)
}

object Sub extends Fn[(Int, Int), Int] {
override protected def f(in: (Int, Int)): Int = in._1 - in._2
}

Fold(Once, Sub)((10, ())) // "left": accumulator - output
// res1: Yield.Some[(Int, Unit), Int, Nothing] = Some(
// out = 7,
// status = Success,
// evolution = ConstEvolution(
// stage = Fold(alterand = <function1>, op = <function1>),
// _dispose = h8io.stages.cycles.Fold$$$Lambda$28756/0x00007fea1f5a6000@34066660
// )
// )
Fold(Once, Swap[Int, Int] ~> Sub)((10, ())) // "right": output - accumulator, via Swap
// res2: Yield.Some[(Int, Unit), Int, Nothing] = Some(
// out = -7,
// status = Success,
// evolution = ConstEvolution(
// stage = Fold(
// alterand = <function1>,
// op = AndThen(upstream = <function1>, downstream = <function1>)
// ),
// _dispose = h8io.stages.cycles.Fold$$$Lambda$28756/0x00007fea1f5a6000@203568e8
// )
// )