I was trying to write my own monad transformers where it would make sense to have multiple of the same monad transformer on the stack with different types. The issue can be illustrated with the reader monad.
The reader monad is offered as a way to hold a read only context of a given type
ex1 :: Reader Bool Bool
ex1 = ask
or
ex2 :: Reader Char Bool
ex2 = pure True
monad transformers allow less restrictive assumptions about the underlining monad
ex3 :: (MonadReader Bool m) => m Bool
ex3 = ask
However, what if I want to have more than 1 read only environment? I can write a function like
ex4 :: (MonadReader Bool m, MonadReader Char m) => m Bool
ex4 = ask
However, as far as I can tell, there is no way to run ex4 since
class Monad m => MonadReader r m | m -> r
means that each MonadReader has a unique reading type. Is there a standard work around for multiple transformers on the same stack? Should I try to avoid this entirely?
lift ask
work? – arrowdm
must uniquely determine the type that is being read. It does work if you use an explicit monad transformer stack instead of the type class though – saraMonadReader
is not a transformer. If you use a transformer, a la thetransformers
package, and avoid thinking in the terms provided bymtl
then you'll do fine. – Thomas M. DuBuisson