# Introducing Monad Transformers and Capabilities

## Comparing `Function input output` to `OutputBox input output`

When we initially covered the original monadic function, `(a -> b)`, we discovered that it's "do notation" could be read like this:

``````produceValue = someComputation 4
where
someComputation = do
five <- (\four -> 1 + four)
three <- (\fourAgain -> 7 - fourAgain)
two <- (\fourOnceMore -> 13 + fourOnceMore - five * three)
(\fourTooMany -> 8 - two + three)
``````

The above computation demonstrates something important: the argument, `4`, passed to `someComputation` is always available in its do notation despite the argument, `4`, never appearing as an argument in `someComputation`'s definition.

``````-- In other words, we have this...
someComputation = do
-- code...

-- ... not this...
someComputation argumentThatIsFour = do
-- some code
``````

The normal `(a -> b)` function allows us to reference the argument we pass into the function at any point in its do notation. Unfortunately, since the return value of that function is `b`, we are limited to only writing pure code. In other words, `someComputation` is a computation that can never interact with the outside world.

But what happens if we use the `OutputMonad`/`(a -> monad b)` function? Since it outputs a monadic data type, what if that monadic data type was `Effect` or `Aff`? If so, the resulting code would be very hard to read:

``````produceComputation = runOutputEffect someComputation 4
where                                                                     {-
someComputation :: OutputMonad a   m      b                               -}
someComputation :: OutputMonad Int Effect String
someComputation = do
five <- (\four -> pure \$ 1 + four)
three <- (\fourAgain -> pure \$ 7 - fourAgain)
intBetween0And12 <- (\fourOnceMore -> randomInt 0 \$ 13 + fourOnceMore - five)
(\fourTooMany -> log \$ show \$ 8 - intBetween0And12)
``````

But what if we expressed the same idea using capabilities via type class constraints? This is the same code as above:

``````produceComputation = runOutputMonad someComputation 4
where
someComputation :: forall m. Monad m =>
someComputation = do
let five = 1 + four
let three = 7 - four
intBetween0And12 <- liftEffect \$ randomInt 0 \$ 13 + four - five
liftEffect \$ log \$ show \$ 8 - intBetween0And12
``````

## Introducing `ReaderT`

To see this from a slighty different angle, we'll cover a few things before linking to an example showing how a computation "evolves" into the `Reader` monad.

`OutputMonad` is better known as `ReaderT`:

• when `ReaderT`'s monadic type is a real monad, we call it `ReaderT`
• when `ReaderT`'s monadic type is `Identity` (placeholder monadic type), we call it `Reader`.

It's corresponding type class is `MonadReader`.

Watch a computation "evolve" into the `Reader` monad in the Monad Reader Example.

### The Main Idea

This is the whole point of using monadic functions that output monadic data types: they allow us to encode all of our business logic as one massive pure function.

If the underlying outputted monadic data type is...then running our code will ...
`Effect`/`Aff`
execute a program
`Identity`^/`Trampoline`^^
allow us test our business logic

^ `Identity` is what you get if `Box` was a newtype rather than data. In other words, `newtype Identity a = Identity a`. `identity` is a function that returns as output its input. Thus, it's often used as a "placeholder" / `mempty` function value. Similarly, `Identity a` is a type that reduces to the `a` type at runtime. Thus, it's often used as a "placeholder" / `mempty`-like monadic type. ^^ `Trampoline` is a monad that we haven't introduced yet.

With one monad, we can prove that our business logic works as expected and does not have any bugs, and with another monad, we can execute that same business logic as a useful program.

This helps us understand the name behind "Monad Transformers". Monadic functions that return other monadic data types (i.e. `a -> m b`) are called "Monad Transformers" because they transform (or augment) the base monad with additional capabilities. They are the "implementation" that makes all of this work.

However, we use type classes like `MonadReader`, `MonadState`, `MonadWriter`, etc. to express that a given computation can only be run if their implementation can satisfy the required capabilities.

In short, we use type classes above to "write" our business logic and monad transformers to "run" our business logic.

### Breaking It Down

First, there is a type class that indicates that some underlying monad has the capability to do some effect (e.g. state manipulation via `MonadState`).

Second, there is a default implementation for that class via a monadic newtyped function (e.g. `ReaderT`). As we will see later, such functions add in specific effects, reduce some of the syntax boilerplate one might write, and make impossible states impossible. When we wish to transform some other monad, we use the newtyped monadic functions that end with `T` as in "transformer" (e.g. `ReaderT`). However, if we don't want to transform a monad (i.e. just use `Identity` to act as a placeholder monadic type), then we remove that `T` (e.g. `Reader`).

Third, the general pattern (there are exceptions!) that we will see reappear when overviewing the other Monad Transformers:

• There is a type class called `Monad[Word]` where `[Word]` clarifies what functions the type class provides. This type class indicates that some underlying monad has some capability.
• There is a single default implementation for `Monad[Word]` called `[Word]T`. When the monad type is specialized to `Identity`, it's simply called `[Word]`.
• To run a computation using `Monad[Word]`, we must use either `run[Word] computation arg` (i.e. the monad is `Identity`) or `run[Word]T computation arg` (i.e. a non-`Identity` monad).

Putting it into a table, we get this.

Type ClassSole Implementation
(`m` is real monad)

function that runs it
Sole Implementation
(`m` is `Identity`)

function that runs it
`Monad[Word]`
(General Pattern)
`[Word]T`

`run[Word]T`
`[Word]`

`run[Word]`
`MonadState``StateT`

`runStateT`
`State`

`runState`
`MonadReader``ReaderT`

`runReaderT`
`Reader`

`runReader`
`MonadWriter``WriterT`

`runWriterT`
`Writer`

`runWriter`
`MonadCont``ContT`

`runCont`
`Cont`

`runCont`
`MonadError``ExceptT`

`runExceptT`
`Except`

`runExcept`

To summarize each monad transformer, we'll use another table. The below terms for "pure" and "impure" refer to whether the computations can interact with the real world.:

A basic function...... is used to run a pure computation ...can be "upgraded" to a monad transformer...... which is used to run an impure computation ...
`input -> output`that depends on its input`globalValue -> monad outputThatUsesGlobalValue`

`ReaderT`
that depends on some global configuration
`state -> Tuple output state`that does state manipulation`oldState -> monad (Tuple (output, newState))`

`StateT`
that does state manipulation
`function \$ arg`once an argument is fully computed`\function -> output`

`ContT`
and periodically use a function passed in as an argument to compute something

Some monad transformers just specify what their output type will be:

A basic return value...... that is used to run a pure computation ...... can be put into a Monad and become a monad transformer...... which is used to run an impure computation ...
`Tuple output additionalOutput`that also produces additional output`monad (Tuple (output, accumulatedValue)`

`WriterT`
that produces accumulated data as additional output
`Either e a`that handles partial functions`monad (Either e a)`

`ExceptT`
that may fail and the error matters
`Maybe a`that might not return a value`monad (Maybe a)`

`MaybeT`
that might not return a value
`List a`that produces 0 or more values`monad (List a)`

`ListT`
that produces 0 or more values

Once again, the "base monad" that usually inhibits `m` in the "stack" of nested monad transformers is usually one of two things:

• `Effect`/`Aff`: impure monads that actually make our business logic useful
• `Identity`/`Free`: pure monads that test our business logic.