Hi, everyone, I’ve finally reached transformers and mtl, still studying it and, as I think, I grasped the main idea. However, I don’t understand types of mtl functions.
Let me explain what I mean
For me, it’s easier to understand Haskell if I write type for each function, for example
instance Functor m => Functor (ReaderT r m) where
fmap :: (a -> b) -> ReaderT r m a -> ReaderT r m b
fmap f m = ReaderT $ \ r -> fmap f $ runReaderT m r
But, as I said, I don’t understand how to apply that to mtl functions
For example:
class Monad m => MonadReader r m | m -> r where
ask :: m r -- < for this one, it's simple, I have to substitute what will be in m
instance Monad m => MonadReader r (ReaderT r m) where
ask :: ReaderT r m r --< and it typechecks, everything is right. cool!
ask = ReaderT $ \ r -> return r
implementation MonadReader for StateT is the following one
instance MonadReader r m => MonadReader r (StateT s m) where
ask :: StateT s m r
ask = lift ask
however, when I want to rewrite it like this, it’s arguing “Couldn’t match type m with ReaderT r m0”
instance MonadReader r m => MonadReader r (StateT s m) where
ask :: StateT s m r
ask = StateT $ \ s -> fmap (, s) $ ReaderT $ \ r -> return r
but if I write like this, it type checks
instance MonadReader r (StateT s (ReaderT r Identity)) where
ask :: StateT s (ReaderT r Identity) r
ask = StateT $ \ s -> fmap (, s) $ ReaderT $ \ r -> return r
I know, that I don’t know a lot, yet and maybe my description is not clear but the main question is: how to rewrite lift ask
with direct implementation StateT $ \ s -> fmap (, s) $ ReaderT $ \ r -> return r
Is there a way of how to write direct implementation? just for studying purposes
Thank you in advance