in algebird-core/src/main/scala/com/twitter/algebird/monad/StateWithError.scala [70:86]
override def run(state: S): Either[F, (S, U)] = {
@annotation.tailrec
def loop(inState: S, st: StateWithError[S, F, Any], stack: List[Any => StateWithError[S, F, Any]]): Any =
st match {
case StateFn(fn) =>
fn(inState) match {
case err @ Left(_) => err // bail at first error
case noError @ Right((newState, out)) =>
stack match {
case head :: tailStack => loop(newState, head(out), tailStack)
case Nil => noError // recursion ends
}
}
case FlatMappedState(st, next) => loop(inState, st, next :: stack)
}
loop(state, this, Nil).asInstanceOf[Either[F, (S, U)]]
}