Skip to content

Instantly share code, notes, and snippets.

@johnynek
Created April 25, 2018 20:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnynek/c06de8ef9f2ccdb103e8fbee65535bfe to your computer and use it in GitHub Desktop.
Save johnynek/c06de8ef9f2ccdb103e8fbee65535bfe to your computer and use it in GitHub Desktop.
// something like this, I didn't actually compile it.
def tailRecM[A, B](a: A)(fn: A => Resource[F, Either[A, B]]): Resource[F, B] = {
def step(adis: (A, F[Unit])): F[Either[(A, F[Unit]), (B, F[Unit])]] = {
val (a, dispose) = dis
val next: F[(Either[A, B], F[Unit])] = fn(a).allocate
// todo: this might not be stack safe, we might
// need a tailRecM type thing on bracket.
def compDisp(d: F[Unit]): F[Unit] =
F.bracket(d)(F.pure)(_ => dispose)
next.map {
case (Left(a), nextDispose) => Left((a, compDisp(nextDispose)))
case (Right(b), nextDispose) => Right((b, compDisp(nextDispose)))
}
}
Resource(Monad[F].tailRecM((a, Monad[F].pure(())))(step))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment