Reputation: 31556
I am learning Monad Transformers and I am trying to learn how to nest Monads.
So let's say I want to create a Future[Either[String, Option[A]]]
So in order to model this shape I did
type Error = String
type FutureEither = EitherT[Future, Error, A]
type FutureEitherOption = OptionT[FutureEither, A]
Now I do
val p1 = 1.pure[FutureEitherOption]
and I get
OptionT(EitherT(Future(Success(Right(Some(1))))))
So this looks correct. I have a 1 inside of an Option which is inside of a Right, Which is inside of a Future Success. Good!
But If I do
Option.empty[Int].pure[FutureEitherOption]
I was hoping that I will get Future(Success(Right(None)))
but I see output
OptionT(EitherT(Future(Success(Right(Some(None))))))
Also, If I want something like
Future(Success(Left("fail")))
If i try to do
val p2 = Left("fail").pure[FutureEitherOption]
The output is weird
OptionT(EitherT(Future(Success(Right(Some(Left(fail)))))))
That's not my shape at all because now there are two Eithers....
Upvotes: 2
Views: 145
Reputation: 4017
1
is of type Int
and so by calling .pure[FutureEitherOption]
you get the right shape:
OptionT(EitherT(Success(Right(Some(1)))))
Option.empty[Int]
is of type Option[Int]
so you need to do:
OptionT[FutureEither, Int](Option.empty[Int].pure[FutureEither])
in order to get the the right shape:
OptionT(EitherT(Success(Right(None))))
Left("fail")
is of type Left[String, Nothing]
(but actually also Either[Error, Option[Int]]
) so you need to do:
OptionT[FutureEither, Int](EitherT[Future, Error, Option[Int]](Either.left[Error, Option[Int]]("fail").pure[Future]))
in order to get the the right shape:
OptionT(EitherT(Success(Left(fail))))
Then you can finally compose all of those. For example you can write a for-comprehension as:
for {
a <- 1.pure[FutureEitherOption]
b <- OptionT[FutureEither, Int](Option.empty[Int].pure[FutureEither])
c <- OptionT[FutureEither, Int](EitherT[Future, Error, Option[Int]](Either.left[Error, Option[Int]]("fail").pure[Future]))
} yield ()
Note: I have explicitly annotated all types in order to let you better understand what its going on.
Upvotes: 3