Skip to content

Instantly share code, notes, and snippets.

@sir-wabbit
Created January 8, 2017 21:23
Show Gist options
  • Select an option

  • Save sir-wabbit/4a36ab9807e624e3fcdd79de622cda6d to your computer and use it in GitHub Desktop.

Select an option

Save sir-wabbit/4a36ab9807e624e3fcdd79de622cda6d to your computer and use it in GitHub Desktop.
trait RMonad[I[_], F[_]] {
def pure[A](ja: I[A]): F[A]
def flatMap[A, B](ma: F[A])(f: I[A] => F[B]): F[B]
}
object RMonad {
import cats.MonadError
implicit def monadError0[E, F[_]](F: MonadError[F, E]): RMonad[Either[E, ?], F] =
new RMonad[Either[E, ?], F] {
def pure[A](ja: Either[E, A]): F[A] = ja match {
case Left(e) => F.raiseError[A](e)
case Right(a) => F.pure[A](a)
}
def flatMap[A, B](ma: F[A])(f: Either[E, A] => F[B]): F[B] =
F.flatMap(F.attempt(ma))(f)
}
implicit def monadError1[E, F[_]](F: RMonad[Either[E, ?], F]): MonadError[F, E] =
new MonadError[F, E] {
override def pure[A](x: A): F[A] = F.pure(Right(x))
override def raiseError[A](e: E): F[A] = F.pure(Left(e))
override def flatMap[A, B](fa: F[A])(f: (A) => F[B]): F[B] = F.flatMap(fa) {
case Right(x) => f(x)
case Left(e) => F.pure(Left(e))
}
override def handleErrorWith[A](fa: F[A])(f: (E) => F[A]): F[A] = F.flatMap(fa) {
case Right(x) => F.pure(Right(x))
case Left(e) => f(e)
}
override def tailRecM[A, B](a: A)(f: (A) => F[Either[A, B]]): F[B] = ???
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment