As far as I can see, we could implement MonadReader s (StateT sm)
instance:
instance MonadReader s (StateT s m) where
ask = get
local f m = do
s <- get
put (f s)
m
put s
ie why it isn't
class MonadReader s m => MonadState s m | s -> m where ...
Similarly we could have Monoid s => MonadWriter s (StateT sm)
instance.
Is there some deep reason between the choice?
This question is motivated by whether MonadError
and MonadWriter
should be super classes of MonadChronicle
Yes, you could do that, but it would violate the spirit of mtl
and potentially lead to API issues. The idea of mtl
is that each standard monad transformer adds one or more distinct effects. Adding StateT
and ReaderT
to the transformer stack give you a state and an environment. If StateT
implemented its own MonadReader
instance, then you'd have access to just the state blob, through two different interfaces. To add an environment to the mix, you'd have to work with the transformers "manually". If you see MonadChronicle
as offering effects you might want to layer on top of writer and exception effects, then you should keep them separate. If you see it as an extension/refinement of those effects, then superclasses make sense.
I think, aside from the nice theoretical/philosophical reasons about the MonadReader
instance for StateT
, I think that the current set-up is also the most practical .
It's more useful to have MonadReader
and MonadState
give different functionality. Then you can leverage ask
and get
to do two different things. If ask
and get
did the same thing, it'd pretty much be redundant functionality. Having them do separate things is much more practical and gives you much more flexibility in the usage of StateT
through its MonadReader
and MonadState
instances/interfaces.
It's a similar reason to why mappend
and <|>
for Maybe
do different things. It'd just be a waste of potential utility :)
I'd imagine that if StateT
gave the same behavior for ask
and get
, people would be complaining about how impractical/limiting it'd be.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.