Scrap your boilerplate
A series of three papers on generic programming in Haskell.
You can find further accompanying examples, libraries, and links on the
Scrap your Boilerplate home page.

The "scrap your boilerplate"
approach to generic programming allows the programmer to
generic functions that can traverse arbitrary data structures,
and yet have type-specific cases. However, the approach requires
all the type-specific cases to be supplied at once, when the function
is defined: the function is closed. In contrast, Haskell's type classes
support open, or extensible functions, that can be extended
with new type-specific cases as new data types are defined. In this
paper we show how to extend the scrap-your-boilerplate approach to support this
open style. On the way we demonstrate the desirablility of
abstraction over type classes, and the usefulness of recursive
dictionaries.

We extend the "scrap your boilerplate" style of generic programming
in Haskell to accomplish an additional range of applications. This
includes several forms of serialisation and de-serialisation, test-set
generation, type validation, and type erasure. To this end, we provide
a well-designed reflection API for datatypes and constructors, and we
also provide more general means of extending generic functions for
given monomorphic or polymorphic types. The presented approach is
readily supported in the GHC implementation of Haskell.

We describe a design pattern that for writing programs
that traverse data structures built from rich mutually-recursive data
types. Such programs often have a great deal
of "boilerplate" code that simply walks the structure, hiding a
small amount of "real" code that constitutes the reason for the
traversal.

Our technique allows most of this boilerplate to be written once and
for all (perhaps even mechanically generated), leaving the programmer free
to concentrate on the important part of the algorithm. These generic
programs are much more robust to data structure evolution because
they contain many fewer lines of type-specific code.

Our approach is simple to understand, reasonably efficient, and it
handles all the data types found in conventional functional
programming languages. It makes essential use of rank-2 polymorphism,
an extension found in some implementations of Haskell.