|Maintainer||Andy Gill <firstname.lastname@example.org>|
This module contains a Template Haskell based generator for the many data-type specific functions that KURE want users to write. KURE Your Boilerplate (KYB) attempts to make writing these function easy. Eventually, there will be a small DSL for effects inside the generated functions.
Unfortunately, you still need to write the
Term instance by hand, because of the use of
type families, a feature that post-dates Template Haskell. You also need to write
the single MyGeneric datatype, which is considered documentation of what you want
KYB to do.
kureYourBoilerplate generates a
Walker instance for every data-type mentioned in your Generic,
Walker instance for the Generic type itself,
and the following for every constructor in every data-structure that is mentioned in Generic.
For exmaple if a constructor is called
Foo, and has type
Foo :: A -> B -> C, we generate
fooR :: (...) => R A -> R B -> R C --congruence over
fooU :: (...,Monoid r) => T A r -> T B r -> T C r --unify the interesting arguments of a
fooG :: (...) => R C --guard for the constructor
fooP :: (...) => (A -> B -> T C a) -> T C a --pattern matching on
withFoo :: (...,Failable f) => (A -> B -> f a) -> C -> f a --application and pattern matching on
Here, R is short for a 'Rewrite m dec', and 'T is short for 'Translate m dec'.
An example of use is
$(kureYourBoilerplate ''MyGeneric [(''Id,''())])
MyGeneric is my universal type,
Id is my monad, and
() is my monoid.
kureYourBoilerplate generates a number of functions for each data-type mentioned in
our given Generic data-type, which we need to provide for KURE, as well as the
The first argument is the name of the Generic data-structure, which you need to write by hand. If you provide the name of a type synonym as the first argument, then KYB assumes that you are acting over a single data-type, i.e. you generic is your AST type. If you provide the name of a data-type (the typical use-case), then this function generates code for every conceptual sub-type of the provided data-type.
The second argument is the monad over which you will be parameterizing your rewrite rules, and the third argument is the monoid over which you will be parameterizing.