# Writer Monad

### Scenario

Imagine you have a function, `f`

which takes in an argument `a`

, produces a result `b`

.

Now, you want log the input in the function.

In languages like Javascript where “functions” can produce side-effects, you could probably capture it in a state variable:

```
let log = "" // We accumulate the logs here
function addOne (n) {
log = log + `Adding one to ${n}`
return n + 1
}
```

In haskell since functions have to be pure, you could do something like this:

```
type Log = String
addOne :: Int -> (Log, Int) -- Embelishing the function to the accumulated log along with the result
addOne n = ("Adding one to " <> show n, n + 1)
```

Continuing on, let’s invoke this function:

```
addedOne :: (Log, Int)
addedOne = addOne 1
```

Now suppose we want to use `addOne`

on `addedOne`

again. We have to lift `addOne`

’s first argument into the `(,) Log`

context..

```
addOne' :: (Log, Int) -> (Log, Int)
addOne' (log, n) = let (log2, n2) = addOne n
in (log ++ log2, n2)
```

*Notice the difference in the type signature for addOne and addOne’*

### Is there some way we can abstract some of this away?

If we observe `log ++ log2`

it seems like a process we will repeat each time, combining `logs`

whenever we call an adding function.

We also know the actual logic is in `addOne`

, not `addOne'`

which is a wrapper around `addOne`

, allowing us to combine the `logs`

.

By abstracting these patterns, we don’t have to write boilerplate code to add the logs each time.

One abstraction we can have is a higher order function which can compose `addOne`

s:

`f :: (Int -> (Log, Int)) -> (Int -> (Log, Int)) -> (Int -> (Log, Int))`

We can observe this resembles the “fish operator”:

`(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)`

We can then try to implement a monadic type here:

```
data WriterL a = WriterL (Log, a)
class Monad WriterL where
return a = ("", a)
f1 >=> f2 = \a -> let (l1, b) = f1 a
(l2, c) = f2 b
in (l1 <> l2, c)
```

```
main :: WriterL Int
main = do
value <- genValues
addOne value
main =
genValues >>=
addOne
genValues :: WriterL Int
genValues = ("1", 1)
("1AddOne ...", 2)
```

We can then use `>=>`

to compose `addOne`

s, composing the underlying functionality and combining the contexts, in this case the logs.

We do realize however, that `a -> m b`

means that the composed function only looks at `a`

.

As such, its treatment of the previous context in `m a`

is fixed, when we defined the `>=>`

operator. It monadically adds the logs.

Hence, we would not be able to `view/read`

the logs along the way if we wanted to. The definition has made the `log`

implicit.

Let’s explore another construct to do `read`

, the Reader Monad.