Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top