The following article is just a few notes on the nature of the Free monad.

```
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
module FreeMaybe where
import Control.Monad (join)
import Control.Monad.Writer.Class
```

There can be just two values of type `Maybe a`

: `Nothing`

and `Just a`

. Now let’s
look at the free monad of `Maybe a`

, `Free Maybe a`

:

```
data Free f a = Pure a | Free (f (Free f a))
instance Functor f => Functor (Free f) where
fmap f (Pure a) = Pure (f a)
fmap f (Free ffa) = Free $ fmap (fmap f) ffa
instance Functor f => Monad (Free f) where
return = Pure
Pure a >>= f = f a
Free ffa >>= f = Free $ fmap (>>= f) ffa
instance (Show a, Show (f (Free f a))) => Show (Free f a) where
showsPrec d (Pure a) = showParen (d > 10) $
showString "Pure " . showsPrec 11 a
showsPrec d (Free m) = showParen (d > 10) $
showString "Free " . showsPrec 11 m
```

There are four “shapes” that values of `Free Maybe a`

can take:

```
Pure a
Free Nothing
Free (Just (Free (Just (... (Free Nothing)))))
Free (Just (Free (Just (... (Free (Pure a))))))
```

In terms of whether a `Free Maybe a`

represents an `a`

or not, `Free Maybe a`

is
equivalent to `Maybe a`

. However, `Maybe a`

is *right adjoint* to `Free Maybe a`

,
meaning that it forgets the structure of `Free Maybe a`

– namely, which of the
four shapes above the value was, and how many occurences of `Free (Just`

there
were.

Why would you ever use `Free Maybe a`

? *Precisely if you cared about the number
of Justs*. Now, say we had a functor that carried other information:

```
data Info a = Info { infoExtra :: String, infoData :: a }
deriving (Show, Functor)
```

Then `Free Info a`

is isomorphic to if `infoExtra`

had been `[String]`

:

```
main :: IO ()
= do
main print $ Free (Info "Hello" (Free (Info "World" (Pure "!"))))
```

Which results in:

```
>>> main
Free (Info {infoExtra = "Hello",
infoData = Free (Info {infoExtra = "World", infoData = Pure "!"})})
it :: ()
```

But now it’s also a `Monad`

, even though we never defined a `Monad`

instance for
`Info`

:

```
main :: IO ()
= do
main print $ do
<- Free (Info "Hello" (Pure "!"))
x <- Free (Info "World" (Pure "!"))
y return $ x ++ y
```

This outputs:

```
>>> foo
Free (Info {infoExtra = "Hello",
infoData = Free (Info {infoExtra = "World", infoData = Pure "!!"})})
it :: ()
```

This works because the Free monad simply accumulates the states of the various
functor values, without “combining” them as a real monadic join would have
done. `Free Info a`

has left it up to us to do that joining later.