I have looked at this to try to understand how several transformer monads interact, and especially getting a better understanding of lift and stacking with monads.
For the RWST monad found here (I think this is the best documentation of it), is it the case that it is a stacked monad where the Reader, Writer, State each are a monadic layer (and in that order of stacking). Or how is it supposed to be understood?
When I look at the definition runRWST :: r -> s -> m (a, s, w) I understand it as taking reader-environment a state-environment and wrapping any monad m around the return value of RWS. This also means that there only exists two layers of monads in this monad. That is, the outer monad m , and a tuple containing several monads.
This in turn also means that you can only use the lift once. Lifting a value from either the reader or the state monad into the outer monad.
In that sense get and ask are just two functions applying one of either two of the inner monads. For this last point I am still not sure I understand why you would need both a reader a state-monad even having read this stackoverflow post. The reader is only meaningfull for read-only I guess, but if one didn't want that, could one use a transformer monad around two seperat state-monads?
An example:
The comments have given me reason to ponder and make the following more explicit.... Of the following type definition what what would be the inner monad, and the outer monad? Is the RWST itself a Monad wrapped around (and therefor an outer monad) Either String (the inner monad) ?
type MyRWST a = RWST
(String -> Either String MyType)
[Int]
(MyEnv, [String], [String])
(Either String)
a
The inner monad of a monad transformer is always a type parameter. The type you've provided isn't a transformer.
This is a
Monad. Compare this to a transformer likeMaybeT.MaybeTtakes two type parameters, and the first itself takes a parameter, so its kind is(* -> *) -> * -> *. With more explicit parentheses, that's(* -> *) -> (* -> *). And now we can see why it's called a transformer. It takes one monad (of kind* -> *) and transforms it into a new monad (also of kind* -> *).RWSTis defined asNow this takes a lot of type arguments, but if we fix
r,w, ands, we get a transformer. That is,RWSTis not, itself, a monad transformer, but for anyr,w, ands,RWST r w sis a transformer. The full kind ofRWSTisAnd while you can think of
RWSTas having three layers (reader, writer, and state), it really only does have one. The "next layer down" ofRWST r w s mis reallym. So to directly answer your question aboutlift, the type signature ofliftisand when
t ~ RWST r w s, we getSo a single
lifttakes us over the wholeRWST r w smess.