Why isn't it necessary to use lift for executing a function in an internal monad transformer environment, except for IO? I mean, if I have StateT over WriterT and WriterT over ReaderT, why can I do this?
tell $ {- any code here for the Writer -}
foo <- asks {- This for the reader -}
and so on...
instead of
lift $ tell $ {- code ... -}
...
Is there an special explanation or it is only the way the Monad Transformers were written?
It's because the Monad Transformer Library (MTL) recognizes that it's quite common for you to stack monads in just that way so they don't define tell
as just some function (Mondoid w) => w -> Writer ()
.
Instead they have MonadWriter
which is defined as a typeclass with tell as a function in it. Then they define a ton of instances of MonadWriter
: ReaderT
, IO
, Writer
(duh) etc. And thus you avoid the annoying repetition of lift.
.
This is quite common, any monad transformer (in MTL) will have a Control.Monad.***.Class
which has this sort of typeclass.
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