# Free monad transformers

This post explains categorically the free construction of *free monad transformers* which can be found in the `free`

library on Hackage.

```
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Free.Monad.Trans where
import Control.Monad
```

Monad transformers are represented by the following type class. `lift`

is a monad morphism between `m`

and `t m`

. `monadTrans`

witnesses the fact that a monad transformer transforms monads into monads; it is not as general as it could be, but we will not need any more power here.

```
class MonadTrans t where
lift :: Monad m => m a -> t m a
monadTrans :: Monad m => (Monad (t m) => t m a) -> t m a
```

`FreeT`

is a functor

```
newtype FreeT f m a = FreeT { runFreeT :: m (FreeF f a (FreeT f m a)) }
data FreeF f a b = Pure a | Free (f b)
deriving Functor
```

Instances are left in the appendix.

The `FreeT`

type maps a functor `f :: * -> *`

to a monad transformer `FreeT f :: (* -> *) -> (* -> *)`

, and that mapping should be functorial. To define that functor, we must first spell out the categories defining the domain and codomain.

This will make `FreeT`

a functor between categories of functors, which is the kind of remark that makes category theory notoriously confusing.

### Domain and codomain

The domain is the category of functors `f :: * -> *`

and natural transformations; the codomain is a category of monad transformers, but it may seem unclear what its morphisms should be. We will try to describe the categorical structures of the domain and codomain in parallel.

A functor `f :: * -> *`

maps a type `a :: *`

to a type `f a :: *`

.

A monad transformer `t :: (* -> *) -> (* -> *)`

maps a monad `m :: * -> *`

to a monad `t m :: * -> *`

.

Types form a category, where morphisms are functions.

Monads form a category, where morphisms are monad morphisms.

A natural transformation `h :: f ~> g`

(a “functor morphism”) between two functors `f, g :: * -> *`

maps a type `a :: *`

to a function `h @a :: f a -> g a`

.

`type f ~> g = forall a. f a -> g a`

A monad transformer morphism `k :: t ~~> u`

between monad transformers `t, u :: (* -> *) -> (* -> *)`

maps a monad `m`

, to a monad morphism `k @m :: forall a. t m a -> u m a`

.

`type t ~~> u = forall m a. Monad m => t m a -> u m a`

A natural transformation `h`

commutes with the functorial mapping `fmap`

.

`h @b . fmap @f = fmap @g . h @a`

A monad transformer morphism `k`

“commutes” with `lift`

.

`k @m . lift @t = lift @u`

### Mapping morphisms

To be a functor, `FreeT`

should map natural transformations `f ~> g`

to monad transformer morphisms `FreeT f ~~> FreeT g`

. This mapping is called `transFreeT`

in the `free`

library.

```
-- Only one of (Functor f) or (Functor g) is actually necessary for the
-- implementation.
transFreeT :: forall f g. Functor g => (f ~> g) -> (FreeT f ~~> FreeT g)
transFreeT h = FreeT . trans . runFreeT
where
trans :: forall m a. Monad m
=> m (FreeF f a (FreeT f m a))
-> m (FreeF g a (FreeT g m a))
trans = fmap @m (fmap @(FreeF g a) (transFreeT h) . transFreeF h)
transFreeF :: (f ~> g) -> (FreeF f a ~> FreeF g a)
transFreeF _ (Pure a) = Pure a
transFreeF h (Free f) = Free (h f)
```

And that mapping should preserve composition.

```
transFreeT id = id
transFreeT (h . i) = transFreeT h . transFreeT i
```

#### Semi-proof

For example, the left hand side of the first equation reduces to:

`transFreeT id = FreeT . fmap (transFreeT id) . runFreeT`

And there’s probably an argument (by induction?) to conclude from there.

`FreeT`

is a left adjoint

A free functor is a left adjoint to a forgetful functor.

Here, `FreeT`

maps a functor `f`

to a monad transformer `FreeT f`

. A corresponding “forgetful functor” should somehow map a monad transformer `t`

to a functor `Forget t`

. Let us find a good functor.

If we use `t`

to transform a well-chosen monad, then we get another monad, which is also a functor, exactly what we’re looking for. We shall choose the identity monad, as it is the most “neutral” of them in some sense. This may be abstractly motivated by the fact that it is the initial object in the category of monads and monad morphisms. It is most straightforwardly represented as a newtype:

`newtype Identity' a = Identity' a`

But it will be a bit more convenient to use the following equivalent representation:

`type Identity a = forall m. Monad m => m a`

Then, the forgetful functor is obtained as:

`type Forget t a = forall m. Monad m => t m a`

We shall use the definition of adjoint functors by Hom isomorphism: there is a natural isomorphism between `f ~> Forget t`

and `FreeT f ~~> t`

. In particular, it consists of a bijection given by the following functions.

Imagine `f`

as specifying *elements of syntax*. The first direction means that if we can interpret these elements individually, then we can interpret an AST as a whole. This is `foldFreeT`

.

```
foldFreeT
:: (Functor f, MonadTrans t) => (f ~> Forget t) -> (FreeT f ~~> t)
foldFreeT h = k
where
k (FreeT m) = monadTrans $ lift m >>= \v -> case v of
Pure a -> return a
Free f -> h f >>= k
```

The other direction seems less useful; it says that every monad transformer morphism out of a free monad transformer can be decomposed as a `foldTreeT`

of some natural transformation, which is equivalent to a straightforward restriction of that morphism.

```
restrict :: Functor f => (FreeT f ~~> t) -> (f ~> Forget t)
restrict k = k . FreeT . return . Free . fmap return
```

The bijection we just gave is *natural*, making this diagram commute for all `k :: FreeT f ~~> t`

, `i :: g ~> f`

and `l :: t ~~> u`

,

```
. restrict
(FreeT f ~~> t) -> (f ~> Forget t)
| |
dimap i (forget l) | | dimap (transFreeT i) l
v restrict v
(FreeT g ~~> u) -> (g ~> Forget u)
-- or as an equation --
forget l . restrict k . i = restrict (l . k . transFreeT i)
```

where `forget`

is the forgetful functorial mapping:

```
forget :: (t ~~> u) -> (Forget t ~> Forget u)
forget k = k
```

and `dimap`

is a bifunctorial mapping:

```
dimap :: (a -> b) -> (c -> d) -> (b -> c) -> (a -> d)
dimap i l k = l . k . i
```

This was a fun exercise in category theory. After figuring it out, I was surprised to see that `foldFreeT`

was not in `free`

, but now it is.

## Appendix

```
instance (Functor f, Monad m) => Functor (FreeT f m) where
fmap = liftM
```

```
instance (Functor f, Monad m) => Applicative (FreeT f m) where
pure = return
(<*>) = ap
```

```
instance (Functor f, Monad m) => Monad (FreeT f m) where
return = FreeT . return . Pure
FreeT m >>= f = FreeT $ m >>= \v -> case v of
Pure a -> runFreeT (f a)
Free w -> return (Free (fmap (>>= f) w))
```

```
instance Functor f => MonadTrans (FreeT f) where
lift = FreeT . fmap Pure
monadTrans t = t
```