# Functorial Blog

by Phil Freeman on 2017/07/01

While thinking about comonads as spaces and Day convolution, I realized an interesting thing. The free applicative functor generated by a comonad `f` is also a comonad.

The free applicative can be defined in a few different ways, but I like to define it like this:

``````data FreeApplicative f a = Pure a | Free (Day f (FreeApplicative f) a)
``````

Here, `Day` is taken from my `purescript-day` package. I think this presentation makes it easy to understand the free applicative, since it is just a Day convolution of a finite number of copies of `f`. It also makes it simple to define various operations like `hoistFreeAp`.

If we refactor this slightly to use a `Coproduct`, then a `Comonad` instance can even be derived:

``````newtype FreeApplicative f a = FreeApplicative (Coproduct Identity (Day f (FreeApplicative f)) a)

derive newtype instance functorFreeApplicative :: Functor f => Functor (FreeApplicative f)
derive newtype instance extendFreeApplicative :: Extend f => Extend (FreeApplicative f)
``````

This works since `Identity` is a comonad, and `Coproduct` and `Day` both preserve comonads.

In the comonads as spaces approach to user interfaces, the free applicative gives a way to build a UI for a finite list of subcomponents, just like `Day` gives us a way to compose two subcomponents.

Unfortunately, `FreeAp` isn't a `Comonad` transformer. The problem is that we would not be able to handle the `Pure` case if we tried to `lower` a `FreeAp w` to a `w`.

However, we can construct a `ComonadTrans` instance if we restrict ourselves to a Day convolution of a non-zero number of copies of `f`. Instead of the free `Applicative`, this gives us the free `Apply`:

``````newtype FreeApplicative f a = FreeApplicative (Coproduct Identity (FreeApply f) a)

derive newtype instance functorFreeApplicative :: Functor f => Functor (FreeApplicative f)
derive newtype instance extendFreeApplicative :: Extend f => Extend (FreeApplicative f)
Now, we can write a `ComonadTrans` instance for `FreeApply` which keeps the first `w` in a non-empty collection of `w`s, and `extract`s the focus from the rest.
``````instance comonadTransFreeApply :: ComonadTrans FreeApply where