简体   繁体   中英

Why MonadReader r (StateT s m) uses an instance of the underlying monad

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM