sealed trait Either[A, B]
case class Left[A, B](a: A) extends Either[A, B]
case class Right[A, B](b: B) extends Either[A, B]
object Either {
implicit def eitherTMonad[A, M[_]: Monad]: Monad[({ type λ[ɑ] = M[Either[A,ɑ]] })#λ] =
new Monad[({ type λ[ɑ] = M[Either[A,ɑ]] })#λ] {
private lazy val m: Monad[M] = implicitly[Monad[M]]
def pure[B](b: B): M[Either[A, B]] =
m.pure(Right(b))
def flatMap[B, C](ma: M[Either[A, B]])(f: B => M[Either[A, C]]): M[Either[A, C]] =
m.flatMap(ma) {
_ match {
case Left(a) => m.pure(Left(a))
case Right(b) => f(b)
}
}
}
implicit def eitherMonad[A]: Monad[({ type λ[ɑ] = Either[A,ɑ] })#λ] =
eitherTMonad[A, ID]
}
Dependencies
Example