| Portability | ghc |
|---|---|
| Stability | unstable |
| Maintainer | Andy Gill <andygill@ku.edu> |
Language.KURE.Boilerplate
Description
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,
a 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 overFoo. -
fooU :: (...,Monoid r) => T A r -> T B r -> T C r --unify the interesting arguments of aFoo. -
fooG :: (...) => R C --guard for the constructorFoo. -
fooP :: (...) => (A -> B -> T C a) -> T C a --pattern matching onFoo. -
withFoo :: (...,Failable f) => (A -> B -> f a) -> C -> f a --application and pattern matching onFoo.
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,''())])
Which means MyGeneric is my universal type, Id is my monad, and () is my monoid.
Documentation
kureYourBoilerplate :: Name -> [(Name, Name)] -> Q [Dec]Source
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
Walker instance.
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.