Template Haskell Tutorial
by Johannes Ahlmann
(this content is available under a simple permissive license)
Template Haskell (TH) is an extension for GHC that allows compile-time meta-programming in Haskell. A meta-program is a program that operates on other programs, such as a compiler or a documentation generator. In TH both the meta-language and the object language are Haskell, and it offers the possibility of representing Haskell code as an Abstract Syntax Tree (AST), which can then be manipulated as a usual data structure.
The TH code is executed at compile-time and is incrementally type checked while substitutions are taking place. This allows type-safe manipulation and creation of Haskell code at compile-time, which enables:
Code Generation; write code that writes code, i.e. (algorithmic program construction, macro-like expansion)
Code Transformation (partial evaluation, reflection, algebraic transformations)
Code Optimisation (domain-specific optimisations, loop unrolling)
Online documentation available for Template Haskell is pretty sparse, but a good overview of TH can be gathered from the original TH paper, a later report, notes of the original authors about version 2 and of course the haddock documentation. There is also the ghc users guide, and various bits on the TemplateHaskell wiki page.
In order to gain the most from this tutorial you should have a minimal understanding of monads and the IO monad and should be fairly confident in Haskell.
Rather than an end-all tutorial to TH that will answer any question you'll ever have, this tutorial is rather a collection of more or less useful examples with some explanations and annotations. For a more structured and detailed approach to TH you might consider some of the above documentation.
Version Compatibility Note: The code examples in this tutorial work with GHC 6.4, but earlier versions of Template Haskell have differing semantics and upcoming versions will very likely see major changes too.
You will need to use the option -fth when compiling any of the following examples. If an example should unexpectedly not run, try to "import Language.Haskell.TH.Syntax" :)
- Compile-Time IO
- A Simple Code Walker
- Recursive Unlooping
- Auto-Generated Deconstructors
The central point of TH is enabling the user to convert between the concrete Haskell syntax and a Haskell readable Abstract Syntax Tree. By manipulating this tree and converting it back into a compiler-internal representation it is possible to do arbitrary transformations on Haskell code.
1.1. Abstract Syntax Tree
An Abstract Syntax Tree is a structured representation of source code. For example the source code
if condition then consequent else alternative