`filter :: (a -> Bool) -> [a] -> [a]`

and then at filterM:

`filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]`

A side-by-side comparison:

```
filter :: (a -> Bool) -> [a] -> [a]
filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]
```

By comparing the type signatures of **filter** and **filterM** we can see that **filterM** is just **filter** where the conditional expression yields a **Bool** within a context **m** and where the matching results are aggregated in the **m** context.

The implementation of **filterM** in GCH base is as follows:

```
filterM :: (Applicative m) => (a -> m Bool) -> [a] -> m [a]
filterM p = foldr (\x -> liftA2 (\flg -> if flg then (x:) else id) (p x)) (pure [])
```

From the above definition it looks like whenever the monadic filter function `(a -> m Bool)`

returns a `m True`

, the value in the supplied list is prepended to an accumulator, and if it doesn’t match the existing accumulator is left unchanged.

Although this sound very simple, I found the usage of **filterM** to be somewhat difficult to understand - at least at first. Let’s start investigating its usage by looking at some example instances for **m**.

Given a list of numbers:

```
numbers :: [Int]
numbers = [1,2,3,4,5]
```

and an **isEven** function:

```
isEven :: Int -> Bool
isEven n = n `mod` 2 == 0
```

we can use **filterM** to filter the list of numbers that are even and return the results in a **Maybe**:

`filterM (Just . isEven) numbers`

which results in:

`Just [2,4]`

That seems pretty easy. Using **filter** on **numbers**:

`filter isEven numbers`

we get:

`[2,4]`

The only difference between the results being that the **filterM** variant has the results in the **Maybe** Monad.

What happens when **filterM** takes a function that can return **Nothing** in some instances?

Given the following function:

```
isDivisibleByThree :: Int -> Bool
isDivisibleByThree n = n `mod` 3 == 0
```

Let’s filter our list of numbers so that they contain even numbers, but if we encounter a number that is divisible by three, we want to bail on the result:

`filterM (\n -> if isDivisibleByThree n then Nothing else Just (isEven n)) numbers`

this results in:

`Nothing`

Now, this might be a little surprising. What happened to all the matches until we encountered a three, such as two? Recall that the **filterM** implementation:

`filterM p = foldr (\x -> liftA2 (\flg -> if flg then (x:) else id) (p x)) (pure [])`

uses **liftA2**:

`liftA2 :: (a -> b -> c) -> f a -> f b -> f c`

to run a binary function over the Applicative instances. With two **Maybe** instances, the result is always **Nothing**, if one of them is **Nothing** as you can’t run the function without both inputs:

```
liftA2 (+) (Just 1) (Just 2) = Just 3
liftA2 (+) (Just 1) Nothing = Nothing
liftA2 (+) Nothing (Just 2) = Nothing
liftA2 (+) Nothing Nothing = Nothing
```

What this demonstrates is that if we ever receive a **Nothing** value while using **filterM** all results up until that point are discarded. This highlights one key difference between **filter** and **filterM**; in addition to filtering on the **Bool** result, **filterM** also combines the results using its Applicative properties.

Let’s run the **filterM** code once again, but this time, we’ll leave out any multiples of three:

`filterM (\n -> if isDivisibleByThree n then Nothing else Just (isEven n)) [1,2,4,5,7,8]`

and this time the answer is:

`Just [2,4,8]`

Let’s try filtering only even numbers using the **IO** Monad:

```
ioFilterM (pure . isEven) numbers
= [2, 4] -- IO [Int]
```

That works as expected. Now let’s introduce a failure in **IO** Monad when a number is divisible by three:

```
filterM (\n -> if isDivisibleByThree n then ioError (userError "boom!") else pure (isEven n)) numbers
= *** Exception: user error (boom!) -- IO [Int]
```

The above discards any results collected once it reaches an **IO** error. This functionality is very similar to how the **Maybe** Monad filtered when it received a **Nothing**. This is quite useful when filtering only valid results and failing on the first failure.

And if we remove any numbers divisible by three:

```
filterM (\n -> if isDivisibleByThree n then ioError (userError "boom!") else pure (isEven n)) [1,2,4,5,7,8]
= [2,4,8] -- IO [Int]
```

we get back the expected results.

With List, things get more interesting. Consider the following:

`filterM (\n -> [True, False]) numbers`

What do you reckon the answer would be? Probably not a powerset:

```
[[1,2,3,4,5],[1,2,3,4],[1,2,3,5],[1,2,3],[1,2,4,5],[1,2,4],[1,2,5],[1,2],
[1,3,4,5],[1,3,4],[1,3,5],[1,3],[1,4,5],[1,4],[1,5],[1],[2,3,4,5],[2,3,4]
,[2,3,5],[2,3],[2,4,5],[2,4],[2,5],[2],[3,4,5],[3,4],[3,5],[3],[4,5],[4],
[5],[]]
```

Remember that **filterM** is defined as:

`filterM p = foldr (\x -> liftA2 (\flg -> if flg then (x:) else id) (p x)) (pure [])`

How does this work with List? If we use **liftA2** with List:

```
liftA2 (+) [1,2,3] [4,5,6]
= [5,6,7,6,7,8,7,8,9]
```

we see that we get a Cartesian product of values (all combinations). List is a non-deterministic Monad and as such it produces results of every possible combination.

Let’s start by expanding out the point-free implementation of **filterM**:

```
filterM p =
foldr (\x acc -> liftA2 (\flg1 accx -> if flg1 then (x:accx) else accx) (p x) acc) (pure [])
```

**accx** is the accumulator value passed to **liftA2**. The values passed will be the Cartesian product of **[True, False]** and the accumulator of list **acc**, which is initially **[[]]**.

There are two main expansions happening in the implementation of **filterM**:

**liftA2**is creating a Cartesian product of the flags**[True, False]**and the accumulator**acc**and combining them with supplied function, which prepends the current value of the list**x**to the accumulator**accx**if the flag is True or returns the existing accumulator**accx**if it is False.- All the combinations returned from
**listA2**are then returned into**foldr**as the new value of the accumulator**acc**.

Because **filterM** is implemented using **foldr** the accumulated values are used from last to first.

Given the following legend:

```
x -- element in the list
acc -- value of accumulator
accx -- value of accumulator at current combination
flg1 -- value of flag at current combination
result -- value of accx after applying flg1
newacc -- value of acc returned to foldr
```

Let’s start from the end of the list at 5 and follow it up to 1.

For the value of 5:

```
x = 5
acc = [[]]
flags = [True, False]
--------------------
accx []
flg1 True
result = 5:[] => [5]
--------------------
accx []
flg1 False
result => []
--------------------
newacc = [[5], []]
```

For the value of 4:

```
x = 4
acc = [[5], []]
flags = [True, False]
--------------------
accx [5]
flg1 True
result = 4:[5] => [4,5]
--------------------
accx []
flg1 True
result = 4:[] => [4]
--------------------
accx [5]
flg1 False
result => [5]
--------------------
accx []
flg1 False
result => []
--------------------
newacc = [[4,5],[4],[5], []]
```

For the value of 3:

```
x = 3
acc = [[4,5],[4],[5], []]
flags = [True, False]
--------------------
accx [4,5]
flg1 True
result = 3:[4,5] => [3,4,5]
--------------------
accx [4]
flg1 True
result = 3:[4] => [3,4]
--------------------
accx [5]
flg1 True
result = 3:[5] => [3,5]
--------------------
accx []
flg1 True
result = 3:[] => [3]
--------------------
accx [4,5]
flg1 False
result => [4,5]
--------------------
accx [4]
flg1 False
result => [4]
--------------------
accx [5]
flg1 False
result => [5]
--------------------
accx []
flg1 False
result => []
--------------------
newacc = [[3,4,5],[3,4],[3,5],[3],[4,5],[4],[5],[]]
```

For the value of 2:

```
x = 2
acc = [[3,4,5],[3,4],[3,5],[3],[4,5],[4],[5],[]]
flags = [True, False]
--------------------
accx [3,4,5]
flg1 True
result = 2:[3,4,5] => [2,3,4,5]
--------------------
accx [3,4]
flg1 True
result = 2:[3,4] => [2,3,4]
--------------------
accx [3,5]
flg1 True
result = 2:[3,5] => [2,3,5]
--------------------
accx [3]
flg1 True
result = 2:[3] => [2,3]
--------------------
accx [4,5]
flg1 True
result = 2:[4,5] => [2,4,5]
--------------------
accx [4]
flg1 True
result = 2:[4] => [2,4]
--------------------
accx [5]
flg1 True
result = 2:[5] => [2,5]
--------------------
accx []
flg1 True
result = 2:[] => [2]
--------------------
accx [3,4,5]
flg1 False
result => [3,4,5]
--------------------
accx [3,4]
flg1 False
result => [3,4]
--------------------
accx [3,5]
flg1 False
result => [3,5]
--------------------
accx [3]
flg1 False
result => [3]
--------------------
accx [4,5]
flg1 False
result => [4,5]
--------------------
accx [4]
flg1 False
result => [4]
--------------------
accx [5]
flg1 False
result => [5]
--------------------
accx []
flg1 False
result => []
--------------------
newacc = [[2,3,4,5],[2,3,4],[2,3,5],[2,3],[2,4,5],[2,4],[2,5],[2],[3,4,5],[3,4],[3,5],[3],[4,5],[4],[5],[]]
```

For the value of 1:

```
x = 1
acc = [[2,3,4,5],[2,3,4],[2,3,5],[2,3],[2,4,5],[2,4],[2,5],[2],[3,4,5],[3,4],[3,5],[3],[4,5],[4],[5],[]]
flags = [True, False]
--------------------
accx [2,3,4,5]
flg1 True
result = 1:[2,3,4,5] => [1,2,3,4,5]
--------------------
accx [2,3,4]
flg1 True
result = 1:[2,3,4] => [1,2,3,4]
--------------------
accx [2,3,5]
flg1 True
result = 1:[2,3,5] => [1,2,3,5]
--------------------
accx [2,3]
flg1 True
result = 1:[2,3] => [1,2,3]
--------------------
accx [2,4,5]
flg1 True
result = 1:[2,4,5] => [1,2,4,5]
--------------------
accx [2,4]
flg1 True
result = 1:[2,4] => [1,2,4]
--------------------
accx [2,5]
flg1 True
result = 1:[2,5] => [1,2,5]
--------------------
accx [2]
flg1 True
result = 1:[2] => [1,2]
--------------------
accx [3,4,5]
flg1 True
result = 1:[3,4,5] => [1,3,4,5]
--------------------
accx [3,4]
flg1 True
result = 1:[3,4] => [1,3,4]
--------------------
accx [3,5]
flg1 True
result = 1:[3,5] => [1,3,5]
--------------------
accx [3]
flg1 True
result = 1:[3] => [1,3]
--------------------
accx [4,5]
flg1 True
result = 1:[4,5] => [1,4,5]
--------------------
accx [4]
flg1 True
result = 1:[4] => [1,4]
--------------------
accx [5]
flg1 True
result = 1:[5] => [1,5]
--------------------
accx []
flg1 True
result = 1:[] => [1]
-------------------- *
accx [2,3,4,5]
flg1 False
result => [2,3,4,5]
--------------------
accx [2,3,4]
flg1 False
result => [2,3,4]
--------------------
accx [2,3,5]
flg1 False
result => [2,3,5]
--------------------
accx [2,3]
flg1 False
result => [2,3]
--------------------
accx [2,4,5]
flg1 False
result => [2,4,5]
--------------------
accx [2,4]
flg1 False
result => [2,4]
--------------------
accx [2,5]
flg1 False
result => [2,5]
--------------------
accx [2]
flg1 False
result => [2]
--------------------
accx [3,4,5]
flg1 False
result => [3,4,5]
--------------------
accx [3,4]
flg1 False
result => [3,4]
--------------------
accx [3,5]
flg1 False
result => [3,5]
--------------------
accx [3]
flg1 False
result => [3]
--------------------
accx [4,5]
flg1 False
result => [4,5]
--------------------
accx [4]
flg1 False
result => [4]
--------------------
accx [5]
flg1 False
result => [5]
--------------------
accx []
flg1 False
result => []
--------------------
newacc = [[1,2,3,4,5],[1,2,3,4],[1,2,3,5],[1,2,3],[1,2,4,5],[1,2,4],[1,2,5],[1,2],[1,3,4,5],[1,3,4],[1,3,5],[1,3],[1,4,5],[1,4],[1,5],[1],[2,3,4,5],[2,3,4],[2,3,5],[2,3],[2,4,5],[2,4],[2,5],[2],[3,4,5],[3,4],[3,5],[3],[4,5],[4],[5],[]]
```

That was a bit harder than necessary!

Using **filterM** with **Either** is pretty much the same as a **Maybe**:

```
let e1 = filterM (\x -> if x == 11 then Left "You gave me eleven" else Right (isEven x))
-- e1 :: :: Integral a => [a] -> Either [Char] [a]
e1 [1 .. 10]
= Right [2,4,6,8,10] -- only even numbers
e1 [1 .. 11]
= Left "You gave me eleven" -- drops all results on a Left
```

Now let’s use a Monad that has two type holes which are both used together. The State Monad allows us to return a value and thread through some state we are interested in at the same time. Let’s use our **isEven** method to filter in all the even inputs and use a list to record all the values inspected along the way:

```
let x1 = filterM (\x -> state (\s -> (isEven(x), s ++ [x]))) [1 .. 10]
-- x1 :: (Integral a, Monad m) => StateT [a] m [a]
evalState x1 [] -- get value
= [2,4,6,8,10] -- only even numbers
execState x1 [] -- get state
= [1,2,3,4,5,6,7,8,9,10] -- the state - all inspected values
```

The interesting thing to note is that given **x1**’s type:

`x1 :: (Integral a, Monad m) => StateT [a] m [a]`

The **m** in **filterM**:

`filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a]`

is:

`StateT [a] m`

which is why we can return a Bool in the value position and have it filter the inputs for us.

Hopefully that was somewhat easier to understand. You can find alternate explanations to this problem here and here.

]]>`stack ghci --package [package-name1] --package [package-name2]`

For example to load the transformers package:

`stack ghci --package transformers`

And now we have transformers loaded in GHCi:

```
*Main Lib> import Control.Monad.
Control.Monad.Fail Control.Monad.Trans.Except
Control.Monad.Fix Control.Monad.Trans.Identity
Control.Monad.IO.Class Control.Monad.Trans.List
Control.Monad.Instances Control.Monad.Trans.Maybe
Control.Monad.ST Control.Monad.Trans.RWS
Control.Monad.ST.Lazy Control.Monad.Trans.RWS.Lazy
Control.Monad.ST.Lazy.Safe Control.Monad.Trans.RWS.Strict
Control.Monad.ST.Lazy.Unsafe Control.Monad.Trans.Reader
Control.Monad.ST.Safe Control.Monad.Trans.State
Control.Monad.ST.Strict Control.Monad.Trans.State.Lazy
Control.Monad.ST.Unsafe Control.Monad.Trans.State.Strict
Control.Monad.Signatures Control.Monad.Trans.Writer
Control.Monad.Trans.Class Control.Monad.Trans.Writer.Lazy
Control.Monad.Trans.Cont Control.Monad.Trans.Writer.Strict
Control.Monad.Trans.Error Control.Monad.Zip
*Main Lib> import Control.Monad.Trans.Writer.Lazy
```

]]>- The validity of an idea or action is determined not by whether it is widely believed or widely reviled but by whether it obeys the rules of logic.
- A statement is true if it cannot be disproved.
- The Socratic Method:
- Locate a statement confidently described as common sense.
- Imagine for a moment that, despite the confidence of the person proposing it, the statement is false.
- Search for situations or contexts where the statement would not be true.
- If an exception is found, the definition must be false or at least imprecise.
- The initial statement must be nuanced to take the exception into account.

- It is by finding out what something is not that one comes closest to understanding what it is.
- We acquire a misplaced respect for others when we concentrate solely on their conclusions – which is why Socrates urged us to dwell on the logic they used to reach them.
- The value of criticism will depend on the thought processes of critics, not on their number or rank.
- We are making vases, we should listen to the advice of those who know about turning glaze into Fe3O4 at 800 ° C; when we are making a ship, it is the verdict of those who construct triremes that should worry us.
- We should not look to Socrates for advice on escaping a death sentence; we should look to him as an extreme example of how to maintain confidence in an intelligent position which has met with illogical opposition.
- Just as medicine confers no benefit if it does not drive away physical illness, so philosophy is useless if it does not drive away the suffering of the mind.
- Before you eat or drink anything, consider carefully who you eat or drink with rather than what you eat or drink: for feeding without a friend is the life of a lion or a wolf.
- Nothing satisfies the man who is not satisfied with a little.
- Could one possess the desired object but not be happy? Could one be happy but not have the desired object?
- We aren’t overwhelmed by anger whenever we are denied an object we desire, only when we believe ourselves entitled to obtain it.
- No, he who has said ‘a day’ has granted too long a postponement to swift misfortune; an hour, an instant of time, suffices for the overthrow of empires.
- We need metaphors to derive a sense of what cannot be seen or touched, or else we will forget.
- The wise man can lose nothing. He has everything invested in himself. The wise man is self-sufficient. If he loses a hand through disease or war, or if some accident puts out one or both of his eyes, he will be satisfied with what is left.
- To calm us down in noisy streets, we should trust that those making a noise know nothing of us.
- Wisdom lies in correctly discerning where we are free to mould reality according to our wishes and where we must accept the unalterable with tranquillity.
- We are like dogs who have been tied to an unpredictable cart.
- We may be powerless to alter certain events, but we remain free to choose our attitude towards them, and it is in our spontaneous acceptance of necessity that we find our distinctive freedom
- That which you cannot reform, it is best to endure.

Upon the highest throne in the world, we are seated, still, upon our arses

Montaigne

- Every man may bear the whole form of the human condition, but it seems that no single country can tolerate the complexity of this condition.
- Friendship is a minor conspiracy against what other people think of as reasonable.

I have seen in my time hundreds of craftsmen and ploughmen wiser and happier than university rectors.

Montaigne

- What reads easily is rarely so written.
- The prudent man strives for freedom from pain, not pleasure.
- What if pleasure and displeasure were so tied together that whoever wanted to have as much as possible of one must also have as much as possible of the other?
- In the mountains of truth you will never climb in vain: either you will get up higher today or you will exercise your strength so as to be able to get up higher tomorrow.

How can anyone become a thinker if he does not spend at least a third of the day without passions, people and books?

Nietzsche

- Not everything which makes us feel better is good for us. Not everything which hurts may be bad.

I’d like to analyse how the Reader instances are derived for each of **Functor**, **Applicative** and **Monad** and test it against some examples to gain some intuition. Also note that (-> r) and (r ->) can be used interchangeably. Thanks to Brian McKenna for that useful titbit.

A functor typeclass is defined as:

```
class Functor f where
fmap, (<$>) :: (a -> b) -> f a -> f b
```

**fmap** or **<$>** basically runs a function (**a -> b**), on a value within some context **f a** and returns the context with the function applied to its value as an **f b**.

```
(a -> b) -- f', a function that requires an 'a' to create a 'b'
f a -- Functor with an 'a'
f (f'(a)) -- apply f' to the 'a'
f b -- the final result of a 'b'
```

Let’s take a look at the **Functor** instance for Maybe:

```
instance Functor Maybe where
-- fmap :: (a -> b) -> f a -> f b
fmap f (Just a) = Just (f a)
fmap _ Nothing = Nothing
```

With **Maybe**, the function **f**, is applied to a value within a **Just** or not applied if the value is a **Nothing**.

When we hear that (-> r) is also a Functor it can boggle our minds a little. How do we define an instance for that?

```
instance Functor (-> r) where
fmap f = -- what goes here?
```

We need a function that takes some resource **r** and returns some other value. Let’s have a crack at deriving the implementation for Functor:

```
instance Functor (r -> ) where
-- fmap :: (a -> b) -> f a -> f b
fmap fab f a = f b -- refer to (a -> b) as fab
fmap fab (\r -> a) = (\r -> b) -- given that the Functor is (r ->), replace 'f' with (r ->)
fmap fab fra = (\r -> b) -- refer to (r -> a) as fra so we can use it
fmap fab fra = (\r -> ??? (fra r)) -- we have an 'r' and we have something that needs an 'r' and returns an 'a'.
fmap fab fra = (\r -> fab (fra r)) -- We have an 'a' and something that needs an 'a' to return a 'b'
fmap fab fra = fab . fra -- we can simplify this to composing fab and fra
```

We are applying the function **fab** to the result of **fra**. It looks like **fmap** takes two functions are composes them.

Compose (.) is defined as:

`(.) :: (b -> c) -> (a -> b) -> a -> c`

or in our case:

`(.) :: (a -> b) -> (r -> a) -> r -> b`

And we can implement the Functor for (r ->) with compose alone:

```
instance Functor (r -> ) where
fmap = (.)
```

This gives us the intuition that fmap over functions is just composition.

Let’s use it on an example:

`fmap (*3) (+100) 1`

What is the result of the above?

Let’s use function composition to get the answer:

```
fmap (*3) (+100) 1
= (\r -> (r + 100) * 3) -- expanding Functor
= ((1 + 100) * 3) -- substituting 1 for 'r'
= 303
```

The Applicative typeclass is defined as:

```
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
```

The **pure** function lifts some value **a** into the **Applicative**, **f**. Also note that **f** is also a **Functor**. The **<$>** function sequences a function from (**a -> b**) within an **Applicative** context, with the value of **a** supplied in another **Applicative** context to produce the result **b** in a third **Applicative** context.

Note the similarities between **<$>** and <*>:

```
fmap, (<$>) :: (a -> b) -> f a -> f b
(<*>) :: f (a -> b) -> f a -> f b
```

The only difference is that with <*> the function is within a context **f**.

```
f (a -> b) -- f', a function within a context 'f', requires an 'a' to create a 'b'
f a -- Applicative Functor with an 'a'
f (f'(a)) -- apply f' to the 'a' within 'f'
f b -- the final result of a 'b'
```

Let’s take a look at the **Applicative** instance for **Maybe**:

```
instance Applicative Maybe where
-- pure :: a -> f a
pure = Just
-- (<*>) :: f (a -> b) -> f a -> f b
(<*>) (Just f) other = fmap f other
(<*>) Nothing _ = Nothing
```

For **Maybe**, **pure** simply creates an instance of **Just** with the supplied value. With <*> the function **f** is within a **Maybe** context. If the context is a **Just**, the function is applied to the other **Maybe** context using **fmap** from the **Functor** typeclass. If the context is a **Nothing**, no function application takes place and a **Nothing** is returned.

How do we define an **Applicative** instance for (r ->) ?

```
instance Applicative (r -> ) where
-- pure :: a -> f a
pure a = \r -> a
-- (<*>) :: f (a -> b) -> f a -> f b
(<*>) f g = \r -> f r (g r) -- f is (\r -> (a -> b)), g is (\r -> a)
```

Apply the input **r** to **g** to return an **a** and also apply **r** to **f**, to return the function from (**a -> b**). Then apply the function (**a -> b**) to **a** to return a **b**.

Let’s use it on an example:

```
(+) <$> (+3) <*> (*100) 5
= (+) <$> (\r -> r + 3) <*> (\r -> r * 100) 5 -- expanding Applicative
= (+) <$> (5 + 3) (5 * 100) -- substituting 5 for 'r'
= 8 + 500 -- combining with (+)
= 508
```

You may also notice that this gives you the same answer as **liftA2**:

```
liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA2 (+) (+3) (*100) 5
= 508
```

The intuition here is that, we can supply the input to each **Applicative** context, and then combine them with a function either through **<$>** or **liftA2**.

And here’s one more example which may seem a little hairy:

```
(\x y z -> [x,y,z]) <$> (+3) <*> (*2) <*> (/2) $ 5
= (\x y z -> [x,y,z]) <$> (\r -> r +3) <*> (\r -> *2) <*> (\r -> /2) $ 5 -- expand Applicative
= (\x y z -> [x,y,z]) <$> (5 + 3) <*> (5 * 2) <*> (5 / 2) -- replace 'r' with 5
= (\x y z -> [x,y,z]) <$> (8.0) <*> (10.0) <*> (2.5)
= [8.0, 10.0, 2.5] -- combine with (\x y z -> [x,y,z])
```

The same result can be achieved with **liftA3**:

```
liftA3 (\x y z -> [x,y,z]) (+3) (*2) (/2) $ 5
= [8.0,10.0,2.5]
```

The **Monad** typeclass is defined as:

```
class Applicative m => Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
```

The **return** function lifts a value **a** into the **Monad** **m**. Bind or (**>>=**) sequentially composes two actions, passing any value produced by the first as an argument to the second.

Let’s take a look at the **Monad** instance for **Maybe** :

```
instance Monad Maybe where
-- (>>=) :: m a -> (a -> m b) -> m b
(Just a) >>= k = k a
Nothing >>= _ = Nothing
```

If the first **Maybe** context is a **Just**, then apply the function **k** to produce a new **Maybe** context. If the first **Maybe** context is a **Nothing**, then return **Nothing**.

How do we define an **Monad** instance for (r ->) ?

```
instance Monad (r ->) where
-- return :: a -> m a
return = pure
-- (>>=) :: m a -> (a -> m b) -> m b
f >>= g = \r -> g (f r) r -- f is (\r -> a), g is (\a -> \r -> b)
```

The **return** function is derived from **pure**, since all **Monads** are also **Applicatives**. The bind function (**>>=**) first applies the input **r** to **f** to give an **a**. It then applies the **a** to **g** to return a function from (**r -> b**). The input **r** is then applied to this function to return the final **b**.

The intuition here is that we supply the input resource **r** to **f** and use that result as the first input to **g** followed by **r** as the second input.

Let’s use it in an example:

```
(+3) >>= (*) $ 5
= (\r -> r + 3) >>= (\a -> \r -> a * r) 5 -- expanding the Monad for 'r'
= (5 + 3) >>= (\a -> a * 5) -- replace 'r' with 5
= (8) >>= (\a -> a * 5)
= (8 * 5) -- replace 'a' with 8
= 40
```

or simply:

```
(+3) >>= (*) $ 5
= ((5+3) * 5)
= (8 * 5)
= 40
```

We can also use the do syntax to solve the above:

```
let z1 = do
x <- (+3)
(x *)
z1 5
= 40
```

The **join** function flattens nested **Monads** and is defined as:

```
join :: (Monad m) => m (m a) -> m a
join x = x >>= id
```

Given the following:

`join (+) 10`

armed with the what we know about **Monads**, what is its result?

```
join (+) 10
-- m (m a) -> m a
= (\r -> (\r -> r + r)) 10 -- expanding the Monad for 'r'
= (10 + 10) -- replacing 'r' with 10
= 20
```

We can also use the do syntax to solve the above:

```
let z2 = do
x <- (+)
x
z2 10
= 20
```

Now stack allows you to send through parameters to your testing framework with the following options:

`--ta,--test-arguments TEST_ARGS Arguments passed in to the test suite program`

So given a full test suite of:

```
RM
exits from home screen: OK
handles invalid query syntax: OK
handle valid query: OK
handle invalid index: OK
handle invalid action: OK
go home from search: OK
quit from search: OK
search without results: OK
```

Using plain Tasty, you can use the -p argument to run tests that match a pattern:

`-p,--pattern ARG Select only tests that match pattern`

Combining the two options, I can choose to run only the *quit from search* test with:

`stack test --ta '-p "quit from search"'`

which results in running only that specific test:

```
RM
quit from search: OK
All 1 tests passed (0.00s)
```

As long as the string you pass to Tasty is specific, you can target tests at different levels (TestGroup, TestCase etc).

For example to only target the *CommandParser* test group I could use:

`stack test --ta '-p "CommandParser"'`

which results in running all the tests with the the *CommandParser* test group:

```
CommandParser
matchValue parser should match one of *?^: OK
matchValue parser should not match other chars: OK
+++ OK, passed 100 tests.
matchType parser should match format: "> [*?^]": OK
query parser should parse a valid query with matches: OK
query parser should parse a valid query with only commands: OK
query parser should parse all valid queries: OK
+++ OK, passed 100 tests.
All 6 tests passed (0.00s)
```

And to target a specific test case within a Test Group I could use the

testGroupName/testName

format.

For example to run the *matchValue parser should not match other chars* test within the *CommandParser* test group, I could use:

`stack test --ta '-p "CommandParser/matchValue parser should not match other chars"'`

which results in:

```
CommandParser
matchValue parser should not match other chars: OK
+++ OK, passed 100 tests.
All 1 tests passed (0.01s)
```

While this great, the version of Tasty I’m using (0.11.3) has support for additional patterns:

An optional prefixed bang ! negates the pattern.

If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a test group. In other words, foo/ will match a group called foo and any tests underneath it, but will not match a regular test foo.

If the pattern does not contain a slash /, the framework checks for a match against any single component of the path. Otherwise, the pattern is treated as a glob, where:

The wildcard * matches anything within a single path component (i.e. foo but not foo/bar).

Two wildcards ** matches anything (i.e. foo and foo/bar).

Anything else matches exactly that text in the path (i.e. foo would only match a component of the test path called foo (or a substring of that form).

For example, group/*1 matches group/test1 but not group/subgroup/test1, whereas both examples would be matched by group/**1. A leading slash matches the beginning of the test path; for example, /test* matches test1 but not group/test1.

Newer versions of Tasty such as 1.0 onward support even more advanced syntax.

Now that’s pretty neat!

]]>I needed to use this stack as I was working with the IO Monad and needed some way to capture the outcomes of a computation (via a Writer) and also needed to supply the initial inputs (via a Reader).

While Reader and Writer Monads on their own seem easy to use, it can be somewhat daunting to try and figure out how to combine the transformer variations of these Monads over some other Monad.

I’m documenting my findings on how to use this stack here for anyone who might be also struggling to figure out how all this stuff hangs together. It is also for my future-self who might need a quick refresher.

Let’s start by looking at the type signature for the Reader Monad:

`r -> a`

The Reader Monad when given some resource, **r** from the environment will return a result of **a**.

The type variables defined are as follows:

- r = resource from the environment
- a = value returned

Next lets have a look at the type signature for a ReaderT Monad Transformer (MT):

`newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }`

This is less clear than the definition of the Reader Monad. As we’ll see below they are essentially very similar.

The type variables defined are as follows:

- r = resource from the environment
- m = the resulting Monad
- a = value returned in the Monad

The ReaderT MT has one extra type variable **m** which is a Monad. If we examine the ReaderT constructor we can see that it encapsulates a type very similar to that of the Reader Monad:

```
r -> m a -- ReaderT MT
r -> a -- Reader Monad
```

The ReaderT MT is simply a Reader Monad whose result is returned within another Monad. More on that later. Hopefully the connection between the Reader Monad and the Reader MT is clearer.

When we see a ReaderT r m a we can mentally substitute it with a function of the type:

`r -> m a`

And when we see a function of the type `r -> m a`

we can mentally substitute it with:

`ReaderT r m a`

Depending on the situation it might be easier to think in one of the above versions of the ReaderT MT.

Given a ReaderT r m a we can unwrap its value via the *runReaderT* method:

`runReaderT :: ReaderT r m a -> r -> m a`

Also given a simple Reader Monad (`r -> a`

) we can lift it into a ReaderT MT with the *reader* or the *asks* function:

`reader,asks :: Monad m => (r -> a) -> ReaderT r m a`

Also note that ReaderT r m is a Monad if **m** is a Monad:

`Monad m => Monad (ReaderT r m)`

This is important to know when using *do* notation with the ReaderT MT as each bind operation will result in a ReaderT r m and not a ReaderT:

```
someFunc :: ReaderT r m a
someFunc = do
r <- ask
return a -- this will be returned into ReaderT r m
```

If you need to wrap a value within a ReaderT MT use:

`ReaderT \r -> -- your value of (m a)`

This might all seem very confusing at the moment. These are different ways of lifting values into the transformer stack at different points. Once you start using the ReaderT MT this will become clearer.

Some other useful functions that work with the ReaderT MT are:

*ask*- to retrieve the supplied resource

`ask :: Monad m => ReaderT r m r`

*local*- to map a function on the resource*before*using it:

`local :: (r -> r) -> ReaderT r m a -> ReaderT r m a`

*mapReaderT*- to change all components of the ReaderT MT except the input type (the inner Monad and result type):

`mapReaderT :: (m a -> n b) -> ReaderT r m a -> ReaderT r n b`

As we’ve not looked at the definitions of the Writer Monad and the WriterT MT let’s do that now. The Writer Monad is defined as:

`(a, w)`

The type variables defined are:

- a = return value
- w = log value (which has to be an Monoid)

The Writer Monad will return a pair of values; a result **a** along with an accumulated log **w**.

The WriterT MT is defined as:

`newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }`

where the type variables defined are:

- a = return value
- m = the resulting Monad
- w = log value (which has to be an Monoid)

Both **a** and **w** are returned as a pair within the Monad **m**.

The WriterT constructor encapsulates:

`m (a, w)`

It’s basically a Writer Monad within another Monad m:

```
(a, w) -- Writer Monad
m (a, w) -- WriterT MT
```

Some other useful functions that work with the WriterT MT are:

*runWriterT*- to unwrap the value of a WriterT MT and return the result and the log:

`runWriterT :: WriterT w m a -> m (a, w)`

*execWriterT*- to unwrap the value of a WriterT MT and return only the log:

`execWriterT :: Monad m => WriterT w m a -> m w`

*tell*- to write a log entry into the WriterT MT:

`tell :: Monad m => w -> WriterT w m ()`

*listen*- to change the result to include the log:

`listen :: Monad m => WriterT w m a -> WriterT w m (a, w)`

*pass*- to run a function on the log to update it:

`pass :: Monad m => WriterT w m (a, w -> w) -> WriterT w m a`

*mapWriterT*- to change all components of the WriterT MT (the inner Monad, result and log type):

`mapWriterT :: (m (a, w) -> n (b, w’)) -> WriterT w m a -> WriterT w’ n b`

Let’s also have a look at the MonadTrans typeclass. It defines one function called *lift*:

`lift :: Monad m => m a -> t m a`

that lifts a Monad into a MT. We can use this function to insert a Monad into a given transformer stack.

Phew! We’ve just had a whirlwind tour of some typeclasses and related functions. Now let’s have a look at an example of using a ReaderT/WriterT transformer stack.

Say we had some configuration about an external service, like its *host* and *port*. We might use a Reader Monad to supply that configuration to the program.

Let’s start by defining a type alias to a Map of String keys and values:

```
import qualified Data.Map.Lazy as M
type Config = M.Map String String
```

Let’s also define a *serverConfig* function to return our populated configuration from a list of key-value pairs:

```
serverConfig :: Config
serverConfig = M.fromList [("host", "localhost"), ("port", "7654")]
```

Let’s definite a function to read the host:

`getHost :: Reader Config (Maybe String)`

Given a *Config* this function will return the host name in a *Just* if present, or a *Nothing* if not.

It would could be implemented as:

```
getHost :: Reader Config (Maybe String)
getHost = do
config <- ask
return (Map.lookup "host" config)
```

First, the *getHost* function requests the Config instance from the environment using the *ask* function. It then looks up the “host” key from that config. Finally it lifts the Maybe value returned from the *lookup* function into the Reader Monad using the *return* function.

Let’s define a function to read the port:

`getPort :: Reader Config (Maybe Int)`

It would could be implemented as:

```
getPort :: Reader Config (Maybe Int)
getPort = do
config <- ask
return (Map.lookup "port" config >>= readMaybe)
```

This function is similar to *getHost* with the additional bind (>>=) operation to join together the value read from *lookup* with *readMaybe*. readMaybe tries to parse a String into a value of type Int in this case. If it successfully parses the value it returns a (*Just Int*) or if it fails it returns a *Nothing*. readMaybe is defined as:

`readMaybe :: Read a => String -> Maybe a`

Also notice that we used a Reader Monad as opposed to a ReaderT MT to read both the host and port. Since the Reader Monad and the ReaderT MT are very similar we can easily convert between them. Why didn’t we use a ReaderT MT directly to read the configuration? We could have, but the ReaderT MT requires an inner Monad m:

`ReaderT r m a`

and we haven’t decided on what **m** is at the moment. I’ll demonstrate how we could have directly used a ReaderT MT to implement *getHost* and *getPort* later on.

Now that we’ve written functions to read the host and port, lets go ahead and use those values in a ReaderT MT along with a WriterT MT to log out the values we received from the configuration:

`getConfig :: ReaderT Config (WriterT String IO) ()`

Given a Config type as an input, the result returned will be in a WriterT MT with a log type of String with an inner Monad of IO and a value of unit () returned within IO. That sounds more complicated than it really is.

It’s implemented as:

```
getConfig :: ReaderT Config (WriterT String IO) ()
getConfig = do
hostM <- fromReader getHost
portM <- fromReader getPort
let host = maybe "-" id hostM
port = maybe "-" show portM
_ <- log "\nConfig"
_ <- log "\n======"
_ <- log (printf "\nhost: %s" host)
_ <- log (printf "\nport: %s" port)
return ()
```

Let’s delve into the implementation of *getConfig*. The first two lines read the host and port into Maybe values from the configuration:

```
hostM <- fromReader getHost
portM <- fromReader getPort
```

The next two lines covert the Maybe values for host and port into their String equivalents:

```
let host = maybe "-" id hostM
port = maybe "-" show portM
```

The next four lines write String values to the log in order:

```
_ <- log "\nConfig"
_ <- log "\n======"
_ <- log (printf "\nhost: %s" host)
_ <- log (printf "\nport: %s" port)
```

and the final line returns a Unit result into the ReaderT r m Monad:

`return ()`

which in this case is the ReaderT (WriterT String IO) Monad.

Let’s look at the type definition of the *fromReader* function:

`fromReader :: Monad m => Reader r a -> ReaderT r m a`

*fromReader* converts a Reader Monad to a ReaderT MT. It is implemented as:

```
fromReader :: Monad m => Reader r a -> ReaderT r m a
fromReader = reader . runReader
```

The *runReader* function is defined as:

`runReader :: Reader r a -> r -> a`

and unwraps the Reader Monad to a function (`r -> a`

). The *reader* function (as defined previously) lifts a function from (`r -> a`

) into the ReaderT MT. This seems like unnecessary work and ideally there should be an in-built function that does this for us.

Next let’s have a look at the *log* function:

```
log :: (Monad m, MonadTrans t, Monoid w) => w -> t (WriterT w m) ()
log = lift . tell
```

From the type definition of *tell*:

`tell :: Monad m => w -> WriterT w m ()`

we can see that we almost get the result we want:

`w -> WriterT w m ()`

We just need to lift the WriterT w m Monad into a Monad Transformer **t** and we can do that with the *lift* defined previously:

`lift :: Monad m => m a -> t m a`

which gives us:

```
w -> WriterT w m () -- tell
m a -> t m a -- lift
-- replacing m with (WriterT w m)
(WriterT w m) a -> t (WriterT w m) a
-- replacing a with ()
(WriterT w m) () -> t (WriterT w m) ()
-- combining lift . tell
w -> t (WriterT w m) ()
```

We can see that we are lifing some log **w** into a transformer stack **t** through the WriterT w m Monad.

We’ve come a long way and we’ve got everything setup as needed. The only thing left to do is run the transformer stack and reap our rewards. We can do that with the *readWriteConfig* function:

```
readWriteConfig :: IO ()
readWriteConfig = execWriterT (runReaderT getConfig serverConfig) >>= putStrLn
```

When running the stack, it is run from outside-in. So given a *ReaderT (WriterT String m) a*, we:

- Run the ReaderT MT:

`r -> m a`

with runReaderT. This returns the result **a** in the inner Monad **m** which is a WriterT String m. Substituting the IO Monad for **m** and Unit for **a** returns a WriterT String IO (). We don’t care about the result of **a** - only the log.

- Run the WriterT MT:

`m (a, w)`

with execWriterT. This returns the log **w** in the inner Monad **m** which is an **m w**. Substituting the IO Monad for **m** and String for **w**, returns an IO String.

- Binding through from IO String to
*putStrLn*gives us an IO (). The final output of running the above is:

```
Config
======
host: localhost
port: 7654
```

I previously mentioned that we could have written the *getHost* and *getPort* functions with a ReaderT MT instead of a Reader Monad. Here’s how we’d do that:

*getHost2*

```
getHost2 :: Monad m => ReaderT Config m (Maybe String)
getHost2 = -- same as getHost
```

Notice that the only difference between *getHost* and *getHost2* is the addition of a new type variable *m* which is a Monad:

```
getHost :: Reader Config (Maybe String) -- Reader Monad
getHost2 :: Monad m => ReaderT Config m (Maybe String) -- ReaderT MT
```

And since we are working with Monads in both cases, the implementation code remains unchanged! So just by changing the type definition of the *getConfig* method we can go from a Reader Monad to a ReaderT MT!

*getPort2*

```
getPort2 :: Monad m => ReaderT Config m (Maybe Int)
getPort2 = -- same as getPort
```

*getConfig2*

```
getConfig2 :: ReaderT Config (WriterT String IO) ()
getConfig2 = do
hostM <- getHost2 -- no need to call fromReader
portM <- getPort2 -- no need to call fromReader
... -- same as getConfig
```

We can see that this solution is a lot easier with less work to do. We just needed to add a Monad type constraint to the *getHost2* and *getPort2* functions. We also have no need for the *fromReader* function which is a bonus! We can also call the *readWriteConfig* function with *getConfig2* instead of *getConfig* and it all works:

*readWriteConfig2*

```
readWriteConfig2 :: IO ()
readWriteConfig2 = execWriterT (runReaderT getConfig2 serverConfig) >>= putStrLn
```

The complete Solution

```
module Config (readWriteConfig) where
import Text.Printf (printf)
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Control.Monad.Trans.Reader
import Control.Monad.Trans.Writer.Lazy
import qualified Data.Map.Lazy as Map
import Data.List (intercalate)
import Data.Functor.Identity (Identity, runIdentity)
import Text.Read (readMaybe)
import Prelude hiding (log)
type Config = Map.Map String String
serverConfig :: Config
serverConfig = Map.fromList [("host", "localhost"), ("port", "7654")]
-- variation with Reader
getHost :: Reader Config (Maybe String)
getHost = do
config <- ask
return (Map.lookup "host" config)
getPort :: Reader Config (Maybe Int)
getPort = do
config <- ask
return (Map.lookup "port" config >>= readMaybe)
fromReader :: Monad m => Reader r a -> ReaderT r m a
fromReader = reader . runReader
log :: (Monad m, MonadTrans t, Monoid w) => w -> t (WriterT w m) ()
log = lift . tell
getConfig :: ReaderT Config (WriterT String IO) ()
getConfig = do
hostM <- fromReader getHost
portM <- fromReader getPort
let host = maybe "-" id hostM
port = maybe "-" show portM
_ <- log "\nConfig"
_ <- log "\n======"
_ <- log (printf "\nhost: %s" host)
_ <- log (printf "\nport: %s" port)
return ()
readWriteConfig :: IO ()
readWriteConfig = execWriterT (runReaderT getConfig serverConfig) >>= putStrLn
-- variation with ReaderT
getHost2 :: Monad m => ReaderT Config m (Maybe String)
getHost2 = do
config <- ask
return (Map.lookup "host" config)
getPort2 :: Monad m => ReaderT Config m (Maybe Int)
getPort2 = do
config <- ask
return (Map.lookup "port" config >>= readMaybe)
getConfig2 :: ReaderT Config (WriterT String IO) ()
getConfig2 = do
hostM <- getHost2
portM <- getPort2
let host = maybe "-" id hostM
port = maybe "-" show portM
_ <- log "\nConfig"
_ <- log "\n======"
_ <- log (printf "\nhost: %s" host)
_ <- log (printf "\nport: %s" port)
return ()
readWriteConfig2 :: IO ()
readWriteConfig2 = execWriterT (runReaderT getConfig2 serverConfig) >>= putStrLn
```

A Monad is based on a type constructor:

`(* -> *)`

which has one type hole; it creates a type when given a type. A simple example is the Maybe Monad:

`Maybe :: * -> *`

While we can create a Monad instance for the Maybe type constructor, a specific Maybe instance like Maybe String can’t have one because it has no type holes:

```
Maybe :: * -> *
(Maybe String) :: * -- no type hole
```

Each Monad Transformer is composed of at least two Monads. If we take ReaderT MT as an example, we have its definition as:

`ReaderT r m a`

where ReaderT r m is a Monad and **m** is also a Monad. If you stack Monads, in the **m** type variable as with a WriterT for example:

`ReaderT r (WriterT w m) a`

then ReaderT r (WriterT w m) is a Monad, WriterT w m is a Monad and **m** is a Monad. Talk about Monad overload!

What we’ve learned so far will help us understand the example from Decoherence I mentioned at the start of this post.

We start off by defining a data type for a Person:

`data Person = Person { name :: String } deriving Show`

We then create a few specific Person instances:

```
alex :: Person
alex = Person "Alex Fontaine"
philip :: Person
philip = Person "Philip Carpenter"
kim :: Person
kim = Person "Kim Lynch"
```

followed by a *peopleDb* function that returns a list of Person instances:

```
peopleDb :: [Person]
peopleDb = [alex, philip, kim]
```

We then define a *process* function as:

`process :: ReaderT Person (WriterT String IO) ()`

and a *process’* function as:

`process' :: ReaderT Person (WriterT String IO) String`

The main difference between the above functions is that one returns a Unit return type and the other returns a String, respectively. Given that the ReaderT MT stack is almost the same as that in the previous example, it should be fairly easy to implement the above functions.

The *process* function is implemented as:

```
process :: ReaderT Person (WriterT String IO) ()
process = do
_ <- log $ "Looking up Person. "
Person p <- ask
_ <- log $ printf "Found person: %s. " p
(liftIO . putStrLn) p
```

We’ve not seen the *liftIO* function before. It’s defined in the MonadIO typeclass as:

`liftIO :: IO a -> m a`

which just lifts a value from the IO Monad into another Monad. In the above example, *liftIO* will lift a Unit value from the IO Monad (`putStrLn p`

), into the ReaderT Person (WriterT String IO) Monad.

The *process’* function is implemented as:

```
process' :: ReaderT Person (WriterT String IO) String
process' = do
_ <- log "Looking up Person... "
Person p <- ask
_ <- log $ printf "Found person: %s. " p
return p
```

Let’s define a function to run the transformer stack:

```
readWritePeople :: IO ()
readWritePeople = do
```

Let’s start by running the *process* function with a Person instance:

```
result1 <- runWriterT (runReaderT process alex) -- :: ((), String)
_ <- (putStrLn . snd) result1
```

Next let’s Run the *process’* function with a Person instance:

```
result2 <- runWriterT (runReaderT process' alex) -- :: (String, String)
_ <- (putStrLn . fst) result2
_ <- (putStrLn . snd) result2
```

Before we look at the next invocation let’s look at the definition of the *mapM* function. The *mapM* function maps each element of a structure to a monadic action, evaluates these actions from left to right, and collects the results.

`mapM :: Monad m => (a -> m b) -> t a -> m (t b)`

*t* is the Traversable typeclass which has a Functor and Foldable constraint:

`class (Functor t, Foldable t) => Traversable t where`

There is also a similarly named mapM_ function:

`mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()`

which just differs from *mapM* in its result:

```
mapM :: (a -> m b) -> t a -> m (t b)
mapM_ :: (a -> m b) -> t a -> m () -- only performs a side effect
```

which it discards (returns Unit). This is useful when you don’t care about the return value and just want to perform some side effect.

Some other interesting functions on the Traversable typeclass are:

- traverse - has the same definition as
*mapM*where the container is an Applicative instead of a Monad:

```
traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
mapM :: Monad m => (a -> m b) -> t a -> m (t b)
```

- sequenceA - Evaluate each action in the structure from left to right, and and collect the results.

`sequenceA :: Applicative f => t (f a) -> f (t a)`

- sequence - Evaluate each monadic action in the structure from left to right, and collect the results.

`sequence :: Monad m => t (m a) -> m (t a)`

*sequence* and *sequenceA* are also Monadic and Applicative variants of each other:

```
sequenceA :: Applicative f => t (f a) -> f (t a)
sequence :: Monad m => t (m a) -> m (t a)
```

There are also `sequence_`

and `sequenceA_`

variants that discard the results of the action.

Let’s use *mapM* to run our ReaderT stack with multiple input values:

```
result3 <- runWriterT (mapM (runReaderT process') peopleDb) -- :: ([String], String)
let people = fst result3
log = snd result3
_ <- putStrLn "\n\nReaderT values:\n"
_ <- mapM_ putStrLn people
_ <- putStrLn "\nWriterT log:\n"
```

The *mapM* function is run as follows:

- Each
*runReaderT process’*is supplied a Person from the*peopleDb*function, which then returns a ReaderT Person (WriterT String IO) String. - These results are then collected as a ReaderT Person (WriterT String IO) [String]

Here’s how we derive the result by replacing each type parameter with the actual types:

```
mapM :: (a -> m b) -> t a -> m (t b)
-- replacing a with Person:
mapM (Person -> m b) t Person -> m (t b)
-- replacing t with []:
mapM (Person -> m b) [Person] -> m [b]
-- replacing m (the Monad) with ReaderT Person (WriterT String IO)
(Person -> ReaderT Person (WriterT String IO) b) -> [Person] -> ReaderT Person (WriterT String IO) [b]
-- replacing b with String
(Person -> ReaderT Person (WriterT String IO) String) -> [Person] -> ReaderT Person (WriterT String IO) [String]
-- which returns the this result:
ReaderT Person (WriterT String IO) [String]
```

The final output is:

```
Alex Fontaine
Looking up Person. Found person: Alex Fontaine.
Alex Fontaine
Looking up Person... Found person: Alex Fontaine.
ReaderT values:
Alex Fontaine
Philip Carpenter
Kim Lynch
WriterT log:
Looking up Person... Found person: Alex Fontaine. Looking up Person... Found person: Philip Carpenter. Looking up Person... Found person: Kim Lynch.
```

I hope this walk-through has made using Monad Transformers a little more approachable.

The code for these examples can be found Github.

**References**

I have been on a roller coaster of many highs and lows. To quote Dickens:

It was the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness

Tomorrow is my last day of work at my current workplace. I don’t know what I’m going to do next, but I know it’s going to be something different. When someone asked me recently what I was going to do after I leave, I said “I was free falling”. That’s what it feels like not to have any immediate plans for your next paying gig.

My resignation had come as a bit of a shock. I didn’t have another job to go to, but I was still quitting. I had been restless for the last three months. It was starting to affect my life outside work. I was exhausted on the weekends. I couldn’t stop talking about how crap work was. I was sick a lot. Stressed. It was time to go. I had looked around for another job but had not found one yet.

Since resigning I feel so much better. I feel happy. Optimistic about the future. Life is good! :)

I know I made the right decision. As I said to my manager when I resigned:

Once you get rid of what you don’t want, you make space for what you do want.

He looked at me like I was crazy.

There were certainly many memorable moments. Here are some of them.

I got this job by an off-hand comment from my friend Andrew. I saw him on a crowded train wearing a t-shirt with a lambda symbol. This made perfect sense since Andrew and I are part of the functional programming scene in Brisbane. Since he was squashed between commuters and the door and I was a few seats down, I sent him a text that read “nice shirt!”. He noticed the text after he got out of the train but replied saying that there was a position going at his work and that I should apply.

A few weeks later I had the job. We spent three months working and bantering together. Unfortunately Andrew was sick of working there. He had been mistreated and lied to. And later after he left, he was unfairly blamed for everything that was wrong with our systems. In reality he had done the impossible and saved the company from the brink of disaster. Strangely no one seemed to care.

At the end of three months, just as I was coming out of my probation, he went to work at another company that appreciated his talents. It was sad to see him go but I was happy I got a chance to work with him.

Six months in, when we were on a hiring spree, my friend Matt came on board. I had worked with him many jobs ago and he had always struck me as someone who I would love to work with again. It’s been great working with him for the last four months and I’m going to miss our daily banter and learning sessions and having someone like-minded to work with.

When I first started work, the chairs we had to sit on were appalling. Rumour had it that they were second-hand chairs that our CTO had acquired twenty years ago. They had been sent straight from his garage to our office. The chairs were in bad shape. I remember a couple of chairs falling apart and the CTO asking for volunteers to make a Frankenchair by combining the two broken chairs.

I had made several complaints about these chairs and they mostly fell on deaf ears, until we IPOed. Once we had more money the clamouring for chairs didn’t seem so nonsensical. My friend Ryan and I were championing this cause. Together with another work colleague Dave, we went to a furniture shop to choose three chairs to “trial”. We had been asked to trial three chairs before the company committed to buying more.

We cabbed it across town and spent a good half-an-hour trying different chairs until we decided on two models. We got an invoice sent to our manager and got back to the office very pleased with ourselves.

Nothing happened for a week. I then injured my back sitting on my crappy chair and refused to come back to work until we had proper chairs. Et voilà! The chairs we had ordered finally arrived on my return. Now we only had three good chairs, the ones Ryan, Dave and myself had chosen. Everyone else in the company was sitting on dilapidated chairs.

Ryan and myself had to campaign for another two weeks, constantly reminding my manager, gathering chair preferences of each employee by insisting that they try one of the two models we had chosen. We finally submitted the order for the new chairs. Accounting didn’t pay the invoice for another week. But in the end, I am happy to say that everyone in the company now has a decent chair to sit on. New recruits automatically get ordered a new chair. A nice small win.

At one point around the three month mark of my tenure, it seemed like someone was resigning every week. We also had a big workload to get through and we were trying to hire Scala developers in a market that had mostly never heard of Scala. Recruiters kept sending us ideal candidates that couldn’t make it through the first ten minutes of an interview. I carried out the interviews with my colleague Dave and we had come up with a simple problem involving Option, which we got candidates to complete on the whiteboard.

If we were not in the office (because all the meeting rooms were taken) we’d take the candidates to a coffee shop, buy them a coffee and then get them to discuss the problem on a sheet of paper.

One thing to note is that we always helped the candidates out if they hit a snag or got nervous and forgot everything that they knew. We also made it a point to explain the solution we were looking for if the candidates failed to reach something reasonable. We gave them pointers, book recommendations, offered pros and cons of their solutions. We spent a long time, usually an hour even with candidates that were not acing it.

If a candidate had failed to come up with a solution, we asked them to study up and learn the how to solve the problem and come back in a few weeks - if they were very keen to work on functional programming. The first four chapters of Functional Programming in Scala book was our recommended reading.

People learn all the time. Just because you don’t know something today, doesn’t mean you won’t know it tomorrow or next week. I wish more workplaces realised that.

I joked with Dave that we were teaching functional programming through the interviews one candidate at a time. :)

I make it a point to go to at least two conferences a year. The YOW! Lambda Jam is one of them and I have been attending since its inception. Naturally I asked to attend and was going to purchase the tickets myself as I always do. I entered into “negotiations” with the company about maybe getting a couple of days off to go for the conference. There seemed to quite a lot of resistance at first, but I went ahead and purchased my tickets and also took annual leave for the two days I needed. If the company was not going to give me the days off I would just use my leave. Not ideal and not very supportive.

In the meantime I convinced a couple of senior developers to come to a YOW! Night - a presentation leading up to the conference. This finally piqued the interest of these developers and they were on board for going to the Lambda Jam - if the company sponsored them and gave them the days off.

I mentioned to my manager that we should send another couple of senior developers to the conference. The senior developers made their case to management as well. I’m not sure why this was such a hard sell. Surely you want your staff skilled up right? Anyway after what seemed like a miracle, the company sponsored three tickets and gave us all leave to go for the conference. The conference was amazing and really opened up the minds of the other developers on the team to the power of functional programming. The weeks following the conference were filled with discussions about Category Theory and various patterns we had heard of at the conference. It transformed the team and made using functional programming to solve problems a viable option.

This was my first professional Scala gig. I had done Scala in my own time, after work and on the weekends, for the last four years. I had written applications which I use everyday. But this was my first Scala “job”.

I loved writing Scala full time.

To really get up to speed on any language you need to use it a lot; for many different things. It was also good to mentor other developers on how to use Scala for functional programming. It has definitely solidified my understanding of many concepts.

I will definitely be looking for another Scala job in the future.

There was a lot of chaos going on daily. Fixes were being rushed into production without any tests. They then broke production. Then another fix was rushed into production to fix the fix. Sometimes that broke too. Every decision was based on how many minutes or hours something was going to take. There was no time to plan any changes or to pay back technical debt.

Dave and I came up with a weekly sprint that had a couple of definite days for releasing to production. On other days we had time to design solutions, make improvements to our code, deployments and pay back technical debt. We had sprint opens where we planned what we were going to do for the next release. We batched the highest priority fixes and features into each release. After a release we had a retrospective where we tried to learn from our past mistakes. This is a typical Agile workflow.

This cadence of constantly delivering quality software lasted for about a good two months. Once the system we were working on was deemed “stable”, we were not allowed to improve it in any way.

We were then thrown onto more prototypical pursuits which mean the death of the cadence we had so carefully nurtured and bankruptcy through technical debt.

The company has a “free lunch on Mondays” policy where the company would buy all employees lunch. The main drawback was that you had to eat it in the office and generally hurry back to your work as soon as you finished. I generally avoided Monday lunches and chose instead to get outside and take a break. This meant I had to buy or bring in my own food on Monday which I had no problems with.

Then our CTO made an announcement that the maximum budget for any person’s lunch was $10. This was bit miserly and the company was not saving that much money with this cutback as opposed to the thousands we were wasting elsewhere. As expected after a while more people started avoiding the free lunch. After what almost seemed like a revolt from the staff, the $10 cap seems to have been lifted. Time will tell.

The company seemed to have a work from home policy - for some people. Some developers worked four days a week. Others seemed to work six or seven. It all depended on what was negotiated with the CTO. Strangely if you had something being delivered, or had some errands to run, then you could “legitimately” work from home. If you just wanted to work from home, you couldn’t. You needed a reason - even a bogus one.

My friend Ryan and I were trying very hard to change this and discussed this with management ad nauseum. We spoke to Human Resources about it. We even spoke to the CEO when he was down visiting from the US. After a long hard battle, it looks like my co-workers will enjoy working from home one day a week. Even once working from home had been “approved”, it was always a “it’s happening next week” kind of thing. So it has yet to happen but I am hopeful that it will at some point. Unfortunately since tomorrow is my last day, like Moses I will not enter the promised land.

What was so frustrating was that we were working with cutting edge technology and rushing things into production all the time. Process changes on the other hand were draconian. If we needed a simple process change, it took more than six months, Human Resource approval and major arm-twisting of the CTO.

At the very start of my tenure I was a coffee nut and joined the resident coffee gang in their two-to-three visits to the coffee shop per day. Over time I came to settle in on what is arguably the best coffee shop in Brisbane: Coffee Anthology. Most people at work were really into their coffee. The caffeine was the ideal accompaniment to the daily stress wheel. We loved coffee so much that we had arranged to have a “coffee class” with Adam, the owner of Anthology. The class was excellent. As fate would have it, I read some articles about the harmful effects of caffeine shortly after and stopped drinking coffee altogether.

Tea became my new beverage of choice, and I brewed my own Oolong and Jasmine tea leaves and stopped visiting coffee shops altogether. Boiling the kettle, infusing the tea and then slowly savouring it became the antidote to the daily stress wheel.

I’ve had many a chat with Ryan at various coffee shops and over many lunches. We spurred each other on to find and read books and articles about the best workplaces in the world and better ways of working, learning and thinking. We also encouraged each other to blog about our thoughts. We tried very hard to makes some positive changes in our current workplace. We won some and but I fear we lost more. But at least we tried.

The team I worked with are awesome. They are a really great bunch of people who I would love to work with again some day in the future under better conditions. It’s a shame they are not given the support they deserve to do the great things they are so easily capable of. I’m going to miss working with them.

It’s been ten months, but it feels like a mini-lifetime.

I’m looking forward to spending more time at home with my family. Working on my own projects is something else I want to do. Maybe some chillaxing and musing thrown in there for good measure.

I have chosen something different for myself. I have done the unthinkable and left a job without having another job in the wings. I have space to think and make some good decisions. I sense something wonderful is just on the horizon.

]]>`~compile`

from within SBT.

For a while there I was stumped about how to do the same for Stack. That was until I stumbled across it in the documentation under Build Synonyms:

`stack build --pedantic --haddock --test --exec "echo Yay, it succeeded" --file-watch`

The flag of interest is **–file–watch**. Now I can continuously watch for file changes against library or test sources and run commands accordingly:

`stack build --file-watch`

or

`stack test --file-watch`

respectively.

]]>The first thing you need to do is bump your SBT version to 0.13.16 or later, as this lets you cross-compile your plugin between 0.13.x and 1.x. Update your **project/build.properties** file with the following:

`sbt.version=0.13.16`

Next we need to update our **build.sbt** file with some new settings.

Change your scala version to 2.12.3:

`scalaVersion := "2.12.3"`

Set the global version of SBT to 1.0.3:

`sbtVersion in Global := "1.0.3"`

Add a **scalaCompilerBridgeSource** setting:

```
scalaCompilerBridgeSource := {
val sv = appConfiguration.value.provider.id.version
("org.scala-sbt" % "compiler-interface" % sv % "component").sources
}
```

Add cross-building versions you require:

`crossSbtVersions := Vector("0.13.16", "1.0.3")`

The full list of changes to **build.sbt** are:

```
scalaVersion := "2.12.3"
sbtVersion in Global := "1.0.3"
scalaCompilerBridgeSource := {
val sv = appConfiguration.value.provider.id.version
("org.scala-sbt" % "compiler-interface" % sv % "component").sources
}
crossSbtVersions := Vector("0.13.16", "1.0.3")
```

*Feel free to change the Scala version to the latest 2.12.x version and SBT to the latest 1.x version* when applying these settings.

Run a clean test across all versions through SBT:

`^ ;clean;test`

The **^** will run all SBT tasks across all versions defined in **crossSbtVersions**. This new syntax is documented here

Here are some of the issues I ran across and their solutions:

For any SBT plugins that your plugin depends on, you need to get the latest version of the plugin that supports 1.x. If the plugin doesn’t support 1.x, you either can’t update your plugin to 1.x or find another plugin or a workaround to get the same functionality without including that plugin.

sbt.Process does not exist in SBT 1.x. This has been removed and you can simply use the Scala’s sys.process.Process instead.

sbt.BuildStructure does not exist in SBT 1.x. This has been moved to sbt.internal.BuildStructure.

There were a lot of deprecated warnings. Please see Migrating from SBT 0.13.x on how to fix them all.

Your plugin is not an AutoPlugin and extends sbt.Plugin instead. SBT 0.13.15 onwards recommends the creation of an AutoPlugin instead of Plugin.

If you have a simple plugin you can do the following:

- Extend AutoPlugin instead of Plugin
- Add an
**autoImport**module under AutoPlugin for any settings you want automatically imported into SBT. - Add the following settings:

```
override def requires = plugins.JvmPlugin
override def trigger = allRequirements
```

Please see sbt-ctags SBT 1x Compatibility PR for an example.

- Scripted failures. The scripted plugin might get different paths to dependencies than it did previously. Simply fix this with the new paths required.

`^ publish`

Should publish both the **sbt/0.13** and **sbt/1.0** versions of your plugin. If you use a service like Bintray you’ll find both versions uploaded when you publish to Bintray.

```
import sbt._
import Keys._
import net.ceedubs.sbtctags.CtagsKeys._
object CustomCtagsSrcDir extends Plugin {
override def settings = Seq(
dependencySrcUnzipDir := baseDirectory.value / ".ctags_srcs"
)
}
```

This different to how it needs to be done in SBT 1.x.

To use sbt-ctags with SBT 1.x first clone the SBT 1x Compatibility PR that publishes sbt-ctags for SBT 1.x.

Next we need to publish this locally as the PR has not been merged as of this writing. This will install the sbt-ctags-0.2.1-SNAPSHOT:

`sbt publishLocal`

Add the sbt-ctags plugin to your **~/.sbt/1.0/plugins/plugins.sbt** file to enable it globally:

`addSbtPlugin("net.ceedubs" %% "sbt-ctags" % "0.2.1-SNAPSHOT")`

Next override the location of your **dependencySrcUnzipDir** directory in **~/.sbt/1.0/global.sbt** globally:

`SbtCtagsKeys.dependencySrcUnzipDir := baseDirectory.value / ".ctags_srcs"`

This is really neat. No more creating unnecessary classes to override settings.

]]>