Skip to content

Instantly share code, notes, and snippets.

@robinp
Created September 8, 2012 12:38
Show Gist options
  • Save robinp/3674515 to your computer and use it in GitHub Desktop.
Save robinp/3674515 to your computer and use it in GitHub Desktop.
Runs a StateT while some state condition is met
object stateTRunner {
def runWhileUsing[F[+_], S, A, B](st: StateT[F, S, A])(init: S, p: S => Boolean, f: (S, A) => B)(implicit F: Monad[F]): F[List[B]] = {
def runWhile0(st: StateT[F, S, A], init: S, accum: List[B]): F[List[B]] = {
if (!p(init)) F.point(accum.reverse)
else F.bind(st.run(init)) {
case (s, a) => runWhile0(st, s, f(s, a) :: accum)
}
}
runWhile0(st, init, Nil)
}
def evalWhile[F[+_], S, A](st: StateT[F, S, A])(init: S, p: S => Boolean)(implicit F: Monad[F]): F[List[A]] =
runWhileUsing(st)(init, p, ((s, a) => a))
}
// Can add runWhile, execWhile, etc.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment