| Copyright | (C) 2008-2013 Edward Kmett | 
|---|---|
| License | BSD-style (see the file LICENSE) | 
| Maintainer | Edward Kmett <ekmett@gmail.com> | 
| Stability | provisional | 
| Portability | MPTCs, fundeps | 
| Safe Haskell | Safe | 
| Language | Haskell2010 | 
Control.Monad.Free.TH
Description
Automatic generation of free monadic actions.
Free monadic actions
makeFree :: Name -> Q [Dec] Source #
$( provides free monadic actions for the
 constructors of the given data type makeFree ''T)T.
makeFree_ :: Name -> Q [Dec] Source #
Like makeFree, but does not provide type signatures.
 This can be used to attach Haddock comments to individual arguments
 for each generated function.
data LangF x = Output String x
makeFree_ 'LangF
-- | Output a string.
output :: MonadFree LangF m =>
          String   -- ^ String to output.
       -> m ()     -- ^ No result.
makeFree_ must be called *before* the explicit type signatures.
makeFreeCon :: Name -> Q [Dec] Source #
$( provides free monadic action for a data
 constructor makeFreeCon 'Con)Con. Note that you can attach Haddock comment to the
 generated function by placing it before the top-level invocation of
 makeFreeCon:
-- | Output a string. makeFreeCon 'Output
makeFreeCon_ :: Name -> Q [Dec] Source #
Like makeFreeCon, but does not provide a type signature.
 This can be used to attach Haddock comments to individual arguments.
data LangF x = Output String x
makeFreeCon_ 'Output
-- | Output a string.
output :: MonadFree LangF m =>
          String   -- ^ String to output.
       -> m ()     -- ^ No result.
makeFreeCon_ must be called *before* the explicit type signature.
Documentation
To generate free monadic actions from a Type, it must be a data
 declaration (maybe GADT) with at least one free variable. For each constructor of the type, a
 new function will be declared.
Consider the following generalized definitions:
data Type a1 a2 … aN param = …
                           | FooBar t1 t2 t3 … tJ
                           | (:+) t1 t2 t3 … tJ
                           | t1 :* t2
                           | t1 `Bar` t2
                           | Baz { x :: t1, y :: t2, …, z :: tJ }
                           | forall b1 b2 … bN. cxt => Qux t1 t2 … tJ
                           | …where each of the constructor arguments t1, …, tJ is either:
- A type, perhaps depending on some of the 
a1, …, aN. - A type dependent on 
param, of the forms1 -> … -> sM -> param, M ≥ 0. At most 2 of thet1, …, tJmay be of this form. And, out of these two, at most 1 of them may haveM == 0; that is, be of the formparam. 
For each constructor, a function will be generated. First, the name of the function is derived from the name of the constructor:
- For prefix constructors, the name of the constructor with the first
   letter in lowercase (e.g. 
FooBarturns intofooBar). - For infix constructors, the name of the constructor with the first
   character (a colon 
:), removed (e.g.:+turns into+). 
Then, the type of the function is derived from the arguments to the constructor:
… fooBar :: (MonadFree Type m) => t1' -> … -> tK' -> m ret (+) :: (MonadFree Type m) => t1' -> … -> tK' -> m ret bar :: (MonadFree Type m) => t1 -> … -> tK' -> m ret baz :: (MonadFree Type m) => t1' -> … -> tK' -> m ret qux :: (MonadFree Type m, cxt) => t1' -> … -> tK' -> m ret …
The t1', …, tK' are those t1 … tJ that only depend on the
 a1, …, aN.
The type ret depends on those constructor arguments that reference the
 param type variable:
- If no arguments to the constructor depend on 
param,ret ≡ a, whereais a fresh type variable. - If only one argument in the constructor depends on 
param, thenret ≡ (s1, …, sM). In particular, ifM == 0, thenret ≡ (); ifM == 1,ret ≡ s1. - If two arguments depend on 
param, (e.g.u1 -> … -> uL -> paramandv1 -> … -> vM -> param, thenret ≡ Either (u1, …, uL) (v1, …, vM). 
Note that Either a () and Either () a are both isomorphic to Maybe a.
 Because of this, when L == 0 or M == 0 in case 3., the type of
 ret is simplified:
ret ≡ Either (u1, …, uL) ()is rewritten toret ≡ Maybe (u1, …, uL).ret ≡ Either () (v1, …, vM)is rewritten toret ≡ Maybe (v1, …, vM).