Safe Haskell | Safe |
---|---|

Language | Haskell2010 |

People commonly misconstrue `Free`

as defining a monad transformer with
`liftF`

behaving like `lift`

, however that approach violates the monad
transformer laws. Another common mistake is to include the base monad as a
term in the functor, which also gives rise to an incorrect monad
transformer.

To solve this, this module provides `FreeT`

, which properly generalizes the
free monad to a free monad transformer which is correct by construction.

The `FreeT`

type commonly arises in coroutine and iteratee libraries that
wish to provide a monad transformer that correctly obeys the monad
transformer laws.

# Free monad transformer

This differs substantially from the non-monad-transformer version because of the requirement to nest the constructors within the base monad.

To deconstruct a free monad transformer, use `runFreeT`

to unwrap it and
bind the result in the base monad. You can then pattern match against the
bound value to obtain the next constructor:

do x <- runFreeT f case x of Return r -> ... Wrap w -> ...

Because of this, you cannot create free monad transformers using the raw
constructors from `FreeF`

. Instead you use the smart constructors `return`

(from `Control.Monad`

) and `wrap`

.

A free monad transformer alternates nesting the base monad `m`

and the base
functor `f`

.

`f`

- The functor that generates the free monad transformer`m`

- The base monad`r`

- The type of the return value

liftF :: (Functor f, Monad m) => f r -> FreeT f m r Source #

Equivalent to `liftF`

from Control.Monad.Free

# Free monad

The `Free`

type is isomorphic to the following simple implementation:

data Free f r = Return r | Wrap (f (Free f r))

... except that if you want to pattern match against those constructors, you
must first use `runFree`

to unwrap the value first.

case (runFreeT f) of Return r -> ... Wrap w -> ...

Similarly, you use the smart constructors `return`

and `wrap`

to build a
value of type `Free`

.