Portability  MPTCs, fundeps 

Stability  provisional 
Maintainer  Edward Kmett <ekmett@gmail.com> 
Safe Haskell  None 
Automatic generation of free monadic actions.
Free monadic actions
makeFree :: Name > Q [Dec]Source
$(makeFree ''Type)
provides free monadic actions for the
constructors of the given type.
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, …, tJ
may 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.
FooBar
turns 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
, wherea
is a fresh type variable.  If only one argument in the constructor depends on
param
, thenret ≡ (s1, …, sM)
. In particular, fM == 0
, thenret ≡ ()
; ifM == 1
,ret ≡ s1
.  If two arguments depend on
param
, (e.g.u1 > … > uL > param
andv1 > … > 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)
.