Skip to content

Instantly share code, notes, and snippets.

@wedens
Created April 14, 2017 16:01
Show Gist options
  • Save wedens/6219d662129b4521c2717082831d2903 to your computer and use it in GitHub Desktop.
Save wedens/6219d662129b4521c2717082831d2903 to your computer and use it in GitHub Desktop.
error effect
sealed trait Error[E, A]
object Error {
case class ThrowError[E, A](error: E) extends Error[E, A]
implicit def monadError[E, S[_]: Functor](implicit I: Inject[Error[E, ?], S]): MonadError[Free[S, ?], E] =
new MonadError[Free[S, ?], E] {
def pure[A](a: A) = Free.pure(a)
def raiseError[A](e: E) = Free.inject[Error[E, ?], S](ThrowError(e))
def handleErrorWith[A](fa: Free[S, A])(f: E => Free[S, A]) =
fa.fold(
r => fa,
s => I.prj(s) match {
case Some(ThrowError(e)) => f(e)
case None => fa
}
)
def flatMap[A, B](fa: Free[S, A])(f: A => Free[S, B]) = fa flatMap f
def tailRecM[A, B](a: A)(f: A => Free[S, Either[A, B]]) = Monad[Free[S, ?]].tailRecM(a)(f)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment