I'm trying to understand how to use Monad Transformers. I read the wiki article about it and still have some questions.
We have IO
monad that needs to read input from user. But the input is not always provided. So it's Option
. To simplify we can define a monad OptionT
which "incapsulates" actions of IO
monad.
In my particular case I have two monads of types Future[Option[String]]
and Future[List[Int]]
. It means to simplify it I need two different transformers ListT[T]
and OptionT[T]
for each monad type respectively in which I embed Future
behavior... Right?
Right, the way monad transformers work is to help you on working with a "inner" monad that is being "transformed" by a "outer" monad.
So F[Option[A]
can be turned into a OptionT[F, A]
(where F
is any monad), which is much easier to work with.
About ListT
, it may not be so easy. For instance cats
doesn't provide one, see their FAQ for more info. As they suggest, you can use Nested
as a replacement for the cases in which you don't need a flatMap
, for example:
import cats._
import cats.implicits._
import cats.data.Nested
import scala.concurrent.Future
import scala.concurrent.Implicits.global
val futList = Future(List(1, 2, 3))
Nested(futList).map(_ + 1).value // Future(List(2, 3, 4))
If you want another take on monad transformers, here's a short article I authored: https://blog.buildo.io/monad-transformers-for-the-working-programmer-aa7e981190e7
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With