I was just looking into monad transformers in real world Haskell. The book said that to make something a monad transformer, you need to make it an instance of the MonadTrans type class.
So the book defined a new Transformer, the MaybeT m a
transformer.
They defined the monadTrans type class for this new transformer:
instance MonadTrans MaybeT where
lift m = MaybeT (Just `liftM` m)
Then they made an instance of MonadState for this transformer:
instance (MonadState s m) => MonadState s (MaybeT m) where
get = lift get
put k = lift (put k)
From what I understand the lift function is taking the underlying monad and wrapping it in the right constructor. However, I do not get the implementation of get or put in the MonadState type class, I would like some help in understanding what the lift is actually doing here. I have also heard that in the mtl package because of how the type classes are defined, you can have a stack of monad transformers with WriterT, StateT etc but you can use functions like get,put,tell etc without actually doing any lifting. I was wondering how does this work, I strongly suspect its to do with these type classes but I am not sure?