Skip to main content

Or

Or tries left first; if left produces no output, it falls back to right. The result is wrapped in scala.util.Either to distinguish which branch supplied the value. right is never applied when left succeeds.

leftrightresult
Some(l)— not applied —Some(Left(l), leftStatus)
NoneSome(r)Some(Right(r), combined)
NoneNoneNone(combined)

Statuses are merged with combine only when both sides are evaluated.

import h8io.stages.*
import h8io.stages.base.*
import h8io.stages.operators.*
object ParseInt extends SAMStage[String, Int, Nothing] {
override def apply(in: String): Yield[String, Int, Nothing] =
in.toIntOption match {
case Some(n) => Yield.Some(n, Status.Success, this)
case None => Yield.None(Status.Success, this)
}
}

object ParseLength extends SAMStage[String, Int, Nothing] {
override def apply(in: String): Yield[String, Int, Nothing] =
Yield.Some(in.length, Status.Success, this)
}

val or = Or(ParseInt, ParseLength)
// or: Or[String, Int, Int, Nothing] = Or(
// left = <function1>,
// right = <function1>
// )
or("42") // left succeeds: Left(42)
// res0: Yield[String, Either[Int, Int], Nothing] = Some(
// out = Left(value = 42),
// status = Success,
// evolution = Evolution(left = <function1>, right = <function1>)
// )
or("hello") // left fails, right succeeds: Right(5)
// res1: Yield[String, Either[Int, Int], Nothing] = Some(
// out = Right(value = 5),
// status = Success,
// evolution = Evolution(left = <function1>, right = <function1>)
// )