| Safe Haskell | Safe |
|---|---|
| Language | Haskell2010 |
Control.Monad.Trans.Free
Contents
Description
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 transformerm- The base monadr- 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.