haskellfunctional-programmingmonadsmonad-transformersstate-monad# Understanding the RWST in Haskell

#### An example:

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?

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
```

Solution

The inner monad of a monad *transformer* is always a type parameter. The type you've provided isn't a transformer.

```
type MyRWST a = RWST
(String -> Either String MyType)
[Int]
(MyEnv, [String], [String])
(Either String)
a
```

This is a `Monad`

. Compare this to a transformer like `MaybeT`

.

`newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }`

`MaybeT`

takes 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 `* -> *`

).

`RWST`

is defined as

`newtype RWST r w s m a = RWST { unRWST :: r -> s -> w -> m (a, s, w) }`

Now this takes a *lot* of type arguments, but if we fix `r`

, `w`

, and `s`

, we get a transformer. That is, `RWST`

is not, itself, a monad transformer, but for any `r`

, `w`

, and `s`

, `RWST r w s`

*is* a transformer. The full kind of `RWST`

is

```
RWST :: * -> * -> * -> (* -> *) -> * -> *
```

And while you can *think* of `RWST`

as having three layers (reader, writer, and state), it really only does have one. The "next layer down" of `RWST r w s m`

is really `m`

. So to directly answer your question about `lift`

, the type signature of `lift`

is

```
lift :: (MonadTrans t, Monad m) => m a -> t m a
```

and when `t ~ RWST r w s`

, we get

```
lift :: Monad m => m a -> RWST r w s m a
```

So a single `lift`

takes us over the *whole* `RWST r w s`

mess.

- Comparing lists in Haskell
- Is there a non-identity monad morphism M ~> M that is monadically natural in M?
- Problem with loading module ‘Distribution.Simple’
- Improving efficiency in Stirling numbers calculation
- Does sequencing an infinite list of IO actions by definition result in a never-ending action? Or is there a way to bail out?
- How to call pgQuery from postgresql-query?
- How to avoid whitespace after a tag (link) in Hamlet templates?
- Understanding type-directed resolution in Haskell with existential types
- Why is seq bad?
- Understanding bind function in Haskell
- How to create route that will trigger on any path in Servant?
- How do I use a global state in WAI middleware?
- nixos 23.11 cabal install mysql-simple problem - "Missing (or bad) C libraries"
- Is there a way to kill all forked threads in a GHCi session without restarting it?
- Why can an invalid list expression such as 2:1 be assigned to a variable, but not printed?
- Iterate over a type level list and call a function based on each type in the list
- How does this solution of Project Euler Problem 27 in the Haskell Wiki work?
- Why `Monad` is required to use `pure`?
- Can't do partial function definitions in GHCi
- recommended way to convert Double -> Float in Haskell
- Haskell profiling understanding cost centre summary for anonymous lambda
- Why is Haskell fully declarative?
- GHC Generating Redundant Core Operations
- Question about Event firing in reflex-frp
- Using Haskell's "Maybe", type declarations
- How can I elegantly invert a Map's keys and values?
- Why there is no output for wrapped IO in Haskell?
- What are the definitions of Weather and Memory in xmobar repo?
- Serializing a Data.Text value to a ByteString without unnecessary \NUL bytes
- Using Haskell with VS Code