https://wiki.haskell.org/api.php?action=feedcontributions&user=Enoksrd&feedformat=atomHaskellWiki - User contributions [en]2024-03-28T11:16:36ZUser contributionsMediaWiki 1.35.5https://wiki.haskell.org/index.php?title=Difference_list&diff=62571Difference list2018-08-01T16:40:02Z<p>Enoksrd: /* Difference lists as functions */ Remove "of the second sort" (made no sense out of context of Wikipedia article it was copy-pasted from), and give code in addition to prose.</p>
<hr />
<div>== Difference lists as functions ==<br />
<br />
A difference list representation of a list <hask>xs :: [T]</hask> is a function <hask>f :: [T] -> [T]</hask>, which when given another list <hask>ys :: [T]</hask>, returns the list that <hask>f</hask> represents, prepended to <hask>ys</hask>. I.e. <hask>f ys = xs ++ ys</hask>.<br />
Whether this kind of difference list is more efficient than another list representations depends on usage patterns.<br />
If an algorithm builds a list by concatenating smaller lists, which are themselves built by concatenating still smaller lists,<br />
then use of difference lists can improve performance by effectively "flattening" the list building computations.<br />
<br />
This can best be exemplified by <hask>show</hask> and <hask>shows</hask> of Prelude, where the first one implements the naive approach and the second one uses difference lists.<br />
Consider showing a binary tree.<br />
<br />
<hask>L-T-R</hask> gives<br />
* <hask> (show L) ++ (show T ++ (show R)) </hask><br />
* <hask> ((show LL) ++ (show LT ++ (show LR))) ++ (show T ++ (show R)) </hask><br />
* <hask> (((show LLL) ++ (show LLT ++ (show LLR))) ++ (show LT ++ (show LR))) ++ (show T ++ (show R)) </hask><br />
<br />
If the tree is large, you end up with a pretty large left association for the left subtree.<br />
True, there's lot of right association, too, but bad enough.<br />
<br />
With difference lists you write<br />
<br />
* <hask> shows L . (shows T . shows R) </hask><br />
* <hask> (shows LL . (shows LT . shows LR)) . (shows T . shows R) </hask><br />
* <hask> ((shows LLL . (shows LLT . shows LLR)) . (shows LT . shows LR)) . (shows T . shows R) </hask><br />
<br />
You still need to resolve three (.) until you get to the first character of the result string,<br />
but for the subsequent characters you do not need to resolve those dots.<br />
In the end, resolution of all (.) may need some time but then concatenation is performed entirely right-associative.<br />
<br />
== Examples ==<br />
<br />
* [[ShowS]] type in the Prelude of Haskell<br />
* The Endo monoid from <hask>Data.Monoid</hask> allows a simple difference list implementation. E.g. <hask>Endo ("bla"++)</hask> represents the list <hask>"bla"</hask>, <hask>mempty</hask> represents the empty list, <hask>mappend</hask> is list concatenation and <hask>appEndo dlist []</hask> converts the difference list <hask>dlist</hask> to a regular list.<br />
* Donald Bruce Stewart's [http://hackage.haskell.org/package/dlist difference list library]<br />
* Bas van Dijk's [http://hackage.haskell.org/package/dstring difference strings library] (which is just a newtype wrapper around a DList Char)<br />
<br />
== See also ==<br />
<br />
* Haskell-Cafe: [http://www.haskell.org/pipermail/haskell-cafe/2008-January/037405.html Difference lists and ShowS]<br />
* Wikipedia on [http://en.wikipedia.org/wiki/Difference_list Difference lists]<br />
<br />
[[Category:Idioms]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=A_practical_Template_Haskell_Tutorial&diff=62535A practical Template Haskell Tutorial2018-06-21T21:58:09Z<p>Enoksrd: /* Shakespearean Templates */ Copy edit</p>
<hr />
<div>This tutorial explores the Glasgow Haskell Compiler's compile-time meta programming in Template Haskell. It motivates use cases for meta programming and explains the different Template Haskell features on simple toy programs. The aim is to give an overview of Template Haskell's functionality in an example-driven manner.<br />
<br />
= Introduction =<br />
<br />
Template Haskell (TH) is the standard framework for doing type-safe, compile-time meta programming in the Glasgow Haskell Compiler (GHC). It allows writing Haskell meta programs, which are evaluated at compile-time, and which produce Haskell programs as the results of their execution.<br />
<br />
Template Haskell was conceived by Tim Sheard and Simon Peyton Jones<ref name="th1" /> by drawing on the ideas of Lisp macros, but in the typed setting of Haskell. Since then, the original implementation has evolved quite a bit<ref name="th2" /><ref name="th3" />. Most notably, in 2007 Geoffrey Mainland added support for quasi quoting<ref name="qq" />, which makes the embedding of domain specific languages into the Haskell host language much easier.<br />
<br />
As it exists today, Template Haskell has two main areas of application: Haskell code generation at compile-time and facilitating the embedding of domain specific languages.<br />
<br />
As a code generator, Template Haskell empowers a user to write many, syntactically different, programs all at once by means of a single meta program. All that is needed is a uniform, algorithmic description to create the different result programs. And the meta program then precisely implements the algorithm to compute all the different result programs as its output. This proves useful for example to avoid writing the same repetitive, boilerplate code over and over again. To this end, Template Haskell is used (among many others) in the <code>aeson</code> library to automatically derive a data type's <code>ToJSON</code> and <code>FromJSON</code> instances for JSON serialization; and in the <code>lens</code> library to mechanically create a data type's lenses.<br />
<br />
As a framework for creating domain specific languages (EDSLs), Template Haskell allows a user to embed programs written in another programming language inside of a Haskell program. This enables writing parts of the program in the concrete, domain specific syntax of a different programming language. It has the benefit to think about -- and to express -- domain specific problems in the language best suited for the task. In particular, it lets a user focus on the domain specific problem and removes all additional language burdens induced by inconvenient syntax, unsuited control constructs, etc. Programs from the embedded language are parsed and translated into corresponding (but syntactically heavier) Haskell code at compile-time by Template Haskell. In this sense, (e.g.,) the shakespearean template languages from the <code>shakespeare</code> library use Template Haskell at their core. They expose succinct domain specific languages to write HTML, CSS, and Javascript code inside of a Haskell based web application.<br />
<br />
= Template Haskell by Examples =<br />
<br />
In this section, we will review the Template Haskell features to write meta programs. The first set of examples show-cases Template Haskell's potential as a code generator; the second set of examples highlights its facilities to create embedded domain specific languages (EDSLs). All examples require GHC's language extension <code>TemplateHaskell</code> to be enabled.<br />
<br />
To avoid confusion in the sequel, we distinguish between meta programs and object programs. Meta programs are the Haskell programs that run at compile-time and which generate Template Haskell object programs as the results of their execution; they are the programs that devise or manipulate other programs by some algorithmic means. Object programs, on the other hand, are the Template Haskell programs manipulated and built by the Haskell meta programs at compile-time.<br />
<br />
== Template Haskell as a Code Generator ==<br />
<br />
As an introductory example, consider Haskell's <code>Prelude</code> function <hask>curry :: ((a,b) -> c) -> a -> b -> c</hask>, which converts a function taking a pair to its curried equivalent. Unfortunately, there are no <code>Prelude</code> functions that provide the same currying functionality for functions taking arbitrary <math>n</math>-tuples. Moreover, having to write more than a few of these functions manually is, while trivial, a very repetitive and cumbersome task. Instead we wish to generate needed <hask>curry3</hask>, <hask>curry5</hask>, or <hask>curry8</hask> functions through a single meta program on demand. Template Haskell lets us do just this. The idea is to write a meta function <hask>curryN :: Int -> Q Exp</hask> which, given a number <code>n >= 1</code>, constructs the ''source code'' for an <math>n</math>-ary <hask>curry</hask> function:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import Control.Monad<br />
import Language.Haskell.TH<br />
<br />
curryN :: Int -> Q Exp<br />
curryN n = do<br />
f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
let args = map VarP (f:xs)<br />
ntup = TupE (map VarE xs)<br />
return $ LamE args (AppE (VarE f) ntup)<br />
</haskell><br />
<br />
For input <math>n</math>, meta function <hask>curryN</hask> builds a lambda abstraction <hask>LamE</hask> that pattern matches against a function <hask>f</hask> and <math>n</math> argument variables <hask>x1</hask>, <hask>x2</hask>, ..., <hask>xn</hask>; in its body, it then applies function <hask>f</hask> to the <math>n</math>-tuple <hask>(x1, x2, ..., xn)</hask> derived from the pattern matched variables. The names used to refer to the variables <hask>f</hask> and <hask>x1</hask> through <hask>xn</hask> are generated monadically by function <hask>newName :: String -> Q Name</hask> to always generate fresh names not used anywhere else. Hence, the value returned by <hask>curryN</hask> is a monadic computation of type <code>Q Exp</code>. When executed, this monadic computation yields an expression <code>Exp</code> representing the object program of an <math>n</math>-ary curry function. For example, <hask>(curryN 3)</hask> returns a monadic computation that yields an expression representing a <hask>curry3</hask> function of type <hask>((a, b, c) -> d) -> a -> b -> c -> d</hask> in abstract syntax.<ref>Note that meta function <hask>curryN</hask> cannot be written in normal Haskell per se as the type for a generated <math>n</math>-ary curry function depends on <math>n</math>. Thus, the definition of <hask>curryN</hask> requires ''dependent types'' to be expressed in Haskell, a feature not yet present. However, there already exist ingenious alternatives to "faking" dependent types in Haskell; see for instance [http://www.brics.dk/RS/01/10/ this paper] for a solution to simulate functions like <hask>curryN</hask> without dependent types).</ref><br />
<br />
<br />
To run a meta program like <hask>curryN</hask> at compile-time, we enclose it with Template Haskell's ''splice'' operator <code>$</code> by writing (e.g.,) <hask>$(curryN 3)</hask>. This evaluates the meta program <code>curryN 3</code> and puts the resulting object program <hask>\f x1 x2 x3 -> f (x1, x2, x3)</hask> in place of the splice. In general, the splice operator <code>$</code> can be applied to any monadic <code>Q</code> computation, hereby performing this computation at compile-time and inserting the resulting object program as real Haskell code. To ensure type safety, meta programs to be run are type checked beforehand to indeed yield a valid Template Haskell object program. Hence, only imported, fully-typechecked meta programs can be run via the splice operator <code>$</code>: in particular, we have to evaluate the meta program <code>$(curryN 3)</code> in a separate module to where <code>curryN</code> is defined.<br />
<br />
To generate function declarations for the first <math>n</math> curry functions, we can devise a further meta program on top of <hask>curryN</hask> as follows:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
Running <hask>$(genCurries 20)</hask> will then splice in the first 20 curry functions at compile-time, namely:<br />
<br />
<haskell><br />
curry1 = \ f x1 -> f (x1)<br />
curry2 = \ f x1 x2 -> f (x1, x2)<br />
curry3 = \ f x1 x2 x3 -> f (x1, x2, x3)<br />
curry4 = \ f x1 x2 x3 x4 -> f (x1, x2, x3, x4)<br />
...<br />
curry20 = \ f x1 x2 ... x20 -> f (x1, x2, ..., x20)<br />
</haskell><br />
<br />
Note that in this case, <hask>genCurries</hask> returns a list of top-level function declarations that bind the anonymous lambda abstractions built by <hask>curryN</hask>. Also, to name the function bindings, we use function <hask>mkName :: String -> Name</hask> instead of <hask>newName :: String -> Q Name</hask>. The reason is that here we want to generate functions <hask>curry1</hask> to <hask>curry20</hask> with exactly the prescribed names, so they can be captured and referred to from other parts of the program.<br />
<br />
Evaluating Haskell (meta) programs at compile-time and splicing in the generated object programs as regular Haskell code is the first central building block of Template Haskell. The two other core mechanisms are exhibited by the implementations of <hask>curryN</hask> and <hask>genCurries</hask>: algebraic data types and the quotation monad <code>Q</code>.<br />
<br />
First, object programs created by Template Haskell are represented as regular algebraic data types, describing a program in the form of an abstract syntax tree. The Template Haskell library provides algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> to represent Haskell's surface syntax of expressions, patterns, declarations, and types, respectively. Virtually every concrete Haskell syntactic construct has a corresponding abstract syntax constructor in one of the four ADTs. Furthermore, all Haskell identifiers are represented by the abstract <code>Name</code> data type. By representing object programs as regular algebraic data types (and thus as data), normal Haskell can be used as the meta programming language to build object programs.<br />
<br />
Second, TH object programs are built inside the quotation monad <code>Q</code>. This monad is performed by the splice operator "<code>$</code>" at compile-time as part of evaluating the meta program. In the examples so far, the <code>Q</code> monad was only needed to provide fresh identifiers with function <hask>newName :: String -> Q Name</hask> for the generated Haskell expressions. The other main feature that requires a monadic construction of object programs is ''reification'', which allows to query compile-time information during the object program's construction. We will explain reification in detail later.<br />
<br />
Thus, Template Haskell's core functionality constitutes evaluating object programs with "<code>$</code>" and building them from algebraic data types inside the quotation monad <code>Q</code>. However, constructing object programs in terms of their abstract syntax trees is quite verbose and leads to clumsy meta programs. Therefore the Template Haskell API also provides two further interfaces to build object programs more conveniently: ''syntax construction functions'' and ''quotation brackets''.<br />
<br />
Syntax construction functions directly relate to the syntax constructors from the algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> for representing Haskell code. However, they hide the monadic nature of building object programs. For example, recall our definition of the <hask>genCurries</hask> meta function from above:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
To use the object program generated by the sub call to <hask>curryN</hask> in the larger context of the returned function declaration, we have to first perform <hask>curryN</hask> and bind its result to <hask>cury</hask>. The reason is that we have to account for <hask>curryN</hask>'s generation of fresh names before we can continue. Using syntax construction functions instead of data constructors, however, abstracts from the monadic construction of <hask>genCurries</hask>, thus making its code a little shorter:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = funD name [clause [] (normalB (curryN ith)) []]<br />
where name = mkName $ "curry" ++ show ith<br />
</haskell><br />
<br />
The new <code>funD</code>, <code>clause</code>, and <code>normalB</code> functions directly correspond to the formerly used <code>FunD</code>, <code>Clause</code>, and <code>NormalB</code> constructors. The only difference lies in their types:<br />
<br />
{|<br />
|-<br />
|<hask>FunD :: Name -> [Clause] -> Dec</hask><br />
|<hask>funD :: Name -> [Q Clause] -> Q Dec</hask><br />
|-<br />
|<hask>Clause :: [Pat] -> Body -> Clause</hask><br />
|<hask>clause :: [Q Pat] -> Q Body -> Q Clause</hask><br />
|-<br />
|<hask>NormalB :: Exp -> Body</hask><br />
|<hask>normalB :: Q Exp -> Q Body</hask><br />
|}<br />
<br />
While the syntax constructors work with raw TH expressions, the syntax construction functions expect their monadic counterparts. They construct a TH object program directly in <code>Q</code>, thus freeing the API consumer from doing the monadic wrapping and unwrapping manually. For every syntax constructor, there is a corresponding monadic syntax construction function provided.<br />
<br />
On top of syntax construction functions, quotation brackets are a further shortcut for representing Haskell code. They allow to specify an object program using just regular Haskell syntax by enclosing it inside oxford brackets <code>[| .. |]</code>. That way, object programs can be specified yet much more succinctly. For example, a meta program building a Haskell expression for the identity function is still quite verbose, if expressed with either ADTs or syntax construction functions:<br />
<br />
<haskell><br />
genId :: Q Exp<br />
genId = do<br />
x <- newName "x"<br />
lamE [varP x] (varE x)<br />
</haskell><br />
<br />
Using quotation brackets, writing the same meta program can be abbreviated much further as:<br />
<br />
<haskell><br />
genId' :: Q Exp<br />
genId' = [| \x -> x |]<br />
</haskell><br />
<br />
Quotation brackets quote regular Haskell code as the corresponding object program fragments inside the <code>Q</code> monad. There are quotation brackets for quoting Haskell expressions (<code>[e| .. |]|</code>), patterns (<code>[p| .. |]</code>), declarations (<code>[d| .. |]</code>), and types (<code>[t| .. |]</code>). Writing <code>[| .. |]</code> is hereby just another way of saying <code>[e| .. |]</code>. Using quotation brackets in a sense ''lifts'' Haskell's concrete syntax into corresponding object program expressions inside the <code>Q</code> monad. By doing so, quotation brackets represent the dual of the already introduced splice operator <code>$</code>: Evaluating a meta program with "<code>$</code>" splices in the generated object program as real Haskell code; in contrast, quotation brackets <code>[| .. |]</code> turn real Haskell code into an object program. Consequently, quotation brackets and the splice operator cancel each other out. The equation <code>$([| e |]) = e</code> holds for all expressions <code>e</code> and similar equations hold for declarations, and types<ref name="th2" />.<br />
<br />
In addition, there is support for quoting Haskell (value and type) identifiers as corresponding <code>Name</code>s inside Template Haskell. This allows to refer to regular Haskell identifiers from within TH object programs. For example, writing <hask>'genId</hask> yields a TH <code>Name</code> referring to the <hask>genId</hask> identifier. Similarly, <hask>''Q</hask> gives a <code>Name</code> referring to the <code>Q</code> type identifier.<br />
<br />
=== Generic Maps ===<br />
<br />
As a second example that uses both syntax construction functions as well as quotation brackets, let's consider a meta program <hask>mapN :: Int -> Q Dec</hask> to build "generic" <hask>map</hask> functions at compile-time. Invoking <hask>$(mapN 1)</hask> should generate the well-known standard function <hask>map :: (a -> b) -> [a] -> [b]</hask>; evaluating <hask>$(mapN 2)</hask> should splice in a binary map function of type <hask>(a -> b -> c) -> [a] -> [b] -> [c]</hask>, and so on.<ref>Note that <math>n</math>-ary maps are better written using Applicative Functors and <code>ZipList</code>s, as this allows to define them first-class from within regular Haskell. For understanding Template Haskell as a code generator, this example is still useful though.</ref><br />
<br />
<haskell><br />
mapN :: Int -> Q Dec<br />
mapN n<br />
| n >= 1 = funD name [cl1, cl2]<br />
| otherwise = fail "mapN: argument n may not be <= 0."<br />
where<br />
name = mkName $ "map" ++ show n<br />
cl1 = do f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
ys <- replicateM n (newName "ys")<br />
let argPatts = varP f : consPatts<br />
consPatts = [ [p| $(varP x) : $(varP ys) |]<br />
| (x,ys) <- xs `zip` ys ]<br />
apply = foldl (\ g x -> [| $g $(varE x) |])<br />
first = apply (varE f) xs<br />
rest = apply (varE name) (f:ys)<br />
clause argPatts (normalB [| $first : $rest |]) []<br />
cl2 = clause (replicate (n+1) wildP) (normalB (conE '[])) []<br />
</haskell><br />
<br />
The implementation of <hask>mapN</hask> is very much in the spirit of meta function <hask>curryN</hask> from the first example. For instance, evaluating splice <hask>$(mapN 3)</hask> splices in the following map function at compile-time:<br />
<br />
<haskell><br />
map3 f (x:xs) (y:ys) (z:zs) = f x y z : map3 f xs ys zs<br />
map3 _ _ _ _ = []<br />
</haskell><br />
<br />
Nonetheless, meta function <hask>mapN</hask> exhibits a couple of new Template Haskell features: First, quotation brackets and splices are used in several places to abbreviate the object program construction. For example, helper definition <hask>apply</hask> used to generate <hask>map3</hask>'s body <hask>f x y z : map3 f xs ys zs</hask> shows the use of quotation brackets; it also highlights how splicing (<hask>$</hask>) and quotes (<hask>[| .. |]</hask>) cancel each other out. Second, identifier quotes (namely, <hask>'[]</hask>) are used to create an object program <code>Name</code> that refers to Haskell's built-in list constructor <hask>[]</hask>. Third, the example advertises how all three APIs for building Template Haskell object programs can be interleaved. The lowermost verbose API of building a raw TH data value inside the quotation monad <code>Q</code> can be abbreviated, where possible, with syntax constructor functions and quotation brackets.<br />
<br />
Lastly, the <hask>mapN</hask> example exemplifies how Haskell's static scoping is extended to object programs. The scoping principle for object programs is just as in normal Haskell: Identifiers are bound to their lexically enclosing binders in scope at the point the object program is ''defined''. Quotation brackets and splices don't alter static scopes, even though splices may bring an object program into scope at a location, where a conflicting closure is present. For example, consider this snippet:<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
static :: Q Exp<br />
static = [| x |]<br />
<br />
plus42 :: Int -> Int<br />
plus42 x = $static + x<br />
</haskell><br />
<br />
Here the occurrence of <hask>x</hask> in <hask>static</hask> refers to the global identifier <hask>x</hask> that is lexically in scope during its definition. Splicing in <hask>static</hask> into a different scope later where a different local <hask>x</hask> is present (i.e., <hask>plus42</hask>'s local identifier <hask>x</hask>), doesn't alter the link between <hask>static</hask>'s <hask>x</hask> and the global identifier <hask>x</hask>.<br />
<br />
The only exception to static scoping in Template Haskell are the names generated by <hask>mkName :: String -> Name</hask>. These names implement dynamic scoping and ''can'' be captured in spliced-in code. Changing the previous snippet to<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
dynamic :: Q Exp<br />
dynamic = VarE (mkName "x")<br />
<br />
times2 :: Int -> Int<br />
times2 x = $dynamic + x<br />
</haskell><br />
<br />
results in the identifier <hask>x</hask> spliced in by <hask>$dynamic</hask> to be bound to the closest <hask>x</hask> in scope. Hence, its binder is <hask>times2</hask>'s local identifier <hask>x</hask> and ''not'' the global <hask>x</hask>.<br />
<br />
=== Reification ===<br />
<br />
The final major Template Haskell feature not yet described is program ''reification''. Briefly, reification allows a meta program to query compile-time information about other program parts while constructing the object program. It allows the meta program to inspect other program pieces to answer questions such as: "what's this variable's type?", "what are the class instances of this type class?", or "which constructors does this data type have and and how do they look like?". The main use case is to generate boilerplate code which ''auto-completes'' manually written code. A prime example is to generically derive type class instances from bare data type definitions.<br />
<br />
Suppose we've defined the following polymorphic data types for representing potentially erroneous values, lists, and binary trees, respectively:<br />
<br />
<haskell><br />
data Result e a = Err e | Ok a<br />
data List a = Nil | Cons a (List a)<br />
data Tree a = Leaf a | Node (Tree a) a (Tree a)<br />
</haskell><br />
<br />
Moreover, suppose we want to derive <code>Functor</code> instances for all of these types. Deriving these instances manually is straightforward, but writing them all out by hand is quite cumbersome. Especially since writing a <code>Functor</code> instance follows the same pattern across all of the above types and in fact any type <code>T a</code>.<br />
<br />
To make a type constructor <code>T</code> an instance of <code>Functor</code>, one needs to implement method <hask>fmap :: (a -> b) -> T a -> T b</hask>. Its definition is hereby precisely determined by parametricity and the functor laws: By parametricity, all values of type <code>a</code> must be replaced according to the provided function with values of type <code>b</code>. Furthermore, by the functor laws, all other shapes of the input value of type <code>T a</code> must be preserved when transforming it to the output value of type <code>T b</code>.<br />
<br />
Meta function <hask>deriveFunctor :: Name -> Q [Dec]</hask> below implements the idea of this algorithm:<br />
<br />
<haskell><br />
data Deriving = Deriving { tyCon :: Name, tyVar :: Name }<br />
<br />
deriveFunctor :: Name -> Q [Dec]<br />
deriveFunctor ty<br />
= do (TyConI tyCon) <- reify ty<br />
(tyConName, tyVars, cs) <- case tyCon of<br />
DataD _ nm tyVars cs _ -> return (nm, tyVars, cs)<br />
NewtypeD _ nm tyVars c _ -> return (nm, tyVars, [c])<br />
_ -> fail "deriveFunctor: tyCon may not be a type synonym."<br />
<br />
let (KindedTV tyVar StarT) = last tyVars<br />
instanceType = conT ''Functor `appT`<br />
(foldl apply (conT tyConName) (init tyVars))<br />
<br />
putQ $ Deriving tyConName tyVar<br />
sequence [instanceD (return []) instanceType [genFmap cs]]<br />
where<br />
apply t (PlainTV name) = appT t (varT name)<br />
apply t (KindedTV name _) = appT t (varT name)<br />
</haskell><br />
<br />
Given the name of a type constructor (e.g. <code>Result</code>, <code>List</code>, etc.), <hask>deriveFunctor</hask> derives the code for this type constructor's <code>Functor</code> instance. For example, running the splice <hask>$(deriveFunctor ''Tree)</hask> generates the following code:<br />
<br />
<haskell><br />
instance Functor Tree where<br />
fmap f (Leaf x) = Leaf (f x)<br />
fmap f (Node l x r) = Node (fmap f l) (f x) (fmap f r)<br />
</haskell><br />
<br />
Meta function <hask>deriveFunctor</hask> shows reification in action. It calls function <hask>reify :: Name -> Q Info</hask> on the input type constructor's name to yield information about this data type's definition. Using <hask>reify</hask>, it thus learns whether the data type was defined using the <code>data</code> or <code>newtype</code> keyword, which constructors it defines and what their shapes are. Based on the learned structure, <hask>deriveFunctor</hask> is then able to generate a suitable definition of <hask>fmap</hask> and its different clauses via the auxiliaries <hask>genFmap</hask>, <hask>genFmapClause</hask>, and <hask>newField</hask>, defined below. These auxiliary definitions generate one <hask>fmap</hask> clause for each of the data type's constructors. And each clause then transforms its constructor by recursively modifying all of the constructor's fields of type <code>a</code> through <hask>fmap</hask>'s function <code>f</code>, while retaining all other shapes.<br />
<br />
<haskell><br />
genFmap :: [Con] -> Q Dec<br />
genFmap cs<br />
= do funD 'fmap (map genFmapClause cs)<br />
<br />
genFmapClause :: Con -> Q Clause<br />
genFmapClause c@(NormalC name fieldTypes)<br />
= do f <- newName "f"<br />
fieldNames <- replicateM (length fieldTypes) (newName "x")<br />
<br />
let pats = varP f:[conP name (map varP fieldNames)]<br />
body = normalB $ appsE $<br />
conE name : map (newField f) (zip fieldNames fieldTypes)<br />
<br />
clause pats body []<br />
<br />
newField :: Name -> (Name, StrictType) -> Q Exp<br />
newField f (x, (_, fieldType))<br />
= do Just (Deriving typeCon typeVar) <- getQ<br />
case fieldType of<br />
VarT typeVar' | typeVar' == typeVar -><br />
[| $(varE f) $(varE x) |]<br />
ty `AppT` VarT typeVar' |<br />
leftmost ty == (ConT typeCon) && typeVar' == typeVar -><br />
[| fmap $(varE f) $(varE x) |]<br />
_ -> [| $(varE x) |]<br />
<br />
leftmost :: Type -> Type<br />
leftmost (AppT ty1 _) = leftmost ty1<br />
leftmost ty = ty<br />
</haskell><br />
<br />
In more detail, <hask>deriveFunctor</hask> works as follows. First, via <hask>reify</hask> it observes the input data type's name <hask>tyConName</hask>, its declared type variables <hask>tyVars</hask>, and its exposed constructors <hask>cs</hask>. It then determines the data type's right-most type variable <hask>tyVar</hask> and stores it together with the data type's type constructor name <hask>tyConName</hask> in the <hask>Q</hask> monad's user state. This state information is retrieved later again from inside auxiliary definition <hask>newField</hask>. Next, <hask>deriveFunctor</hask> derives a <hask>Functor</hask>'s <hask>fmap</hask> definition using auxiliary <hask>genFmap</hask>. For each of the input data type's value constructors <hask>cs</hask>, <hask>genFmap</hask> generates an <hask>fmap</hask> clause using helper function <hask>genFmapClause</hask>. The latter recursively maps the provided function <hask>f :: a -> b</hask> over all of a constructor's fields of type <code>a</code>, while leaving all other fields untouched. Each field is hereby modified through <hask>f</hask> or left unchanged by auxiliary <hask>newField</hask> based on the field's type: if a field's type is <code>a</code> (which is stored in the retrieved <hask>tyVar</hask> inside function <hask>newField</hask>), then <hask>f</hask> needs to be applied to it; otherwise it needs to remain unchanged.<br />
<br />
<br />
In an analogous manner to <hask>deriveFunctor</hask>, a function <hask>deriveFoldable :: Name -> Q [Dec]</hask> can be devised to derive a data type's <code>Foldable</code> instance. All that is needed is to provide a definition for function <hask>foldMap :: Monoid m => (a -> m) -> T a -> m</hask>. Again, <hask>foldMap</hask>'s definition follows directly from a data type's bare definition, which can be observed by means of reification. This highlights particularly how the functionality offered by Template Haskell provides a low-level API into the GHC compiler to manipulate abstract syntax trees at compile-time. This mechanism is quite powerful and even allows to simulate some of GHC's offered language extensions, e.g., <code>-XDeriveFunctor</code> and <code>-XDeriveFoldable</code>, to be implemented as a library on top of Template Haskell.<br />
<br />
== Template Haskell for building Embedded Domain specific Languages (EDSLs) ==<br />
<br />
To see Template Haskell's potential for building an EDSL, consider the problem of pattern matching text with regular expressions. Suppose, as part of a Haskell program we need to devise many different regular expressions and use them to pattern match text fragments. Regular expressions are easily defined by an algebraic data type capturing their structure, as well as an evaluator checking whether a regular expression matches some input string. <ref>This example draws on Penn's CIS 552 ''Advanced Programming'' course, specifically Assignment 5: http://www.seas.upenn.edu/~cis552/current/hw/hw05/Main.html.</ref><br />
<br />
<haskell><br />
data RegExp<br />
= Char (Set Char) -- [a], [abc], [a-z]; matches a single character from the specified class<br />
| Alt RegExp RegExp -- r1 | r2 (alternation); matches either r1 or r2<br />
| Seq RegExp RegExp -- r1 r2 (concatenation); matches r1 followed by r2<br />
| Star RegExp -- r* (Kleene star); matches r zero or more times<br />
| Empty -- matches only the empty string<br />
| Void -- matches nothing (always fails)<br />
| Var String -- a variable holding another regexp (explained later)<br />
deriving Show<br />
<br />
match :: RegExp -> String -> Bool<br />
match r s = nullable (foldl deriv r s)<br />
</haskell><br />
<br />
The evaluator <hask>match</hask> is hereby based on the concept of derivatives<ref name="regexp-derivs" />: an initial regular expression <hask>r</hask> matches an input string <hask>s</hask>, if <hask>r</hask> matches the first character of <hask>s</hask> and its derivative regular expression <hask>(deriv r)</hask> matches the remainder of <hask>s</hask>:<br />
<br />
<haskell><br />
nullable :: RegExp -> Bool<br />
nullable (Char _) = False<br />
nullable (Alt r1 r2) = nullable r1 || nullable r2<br />
nullable (Seq r1 r2) = nullable r1 && nullable r2<br />
nullable (Star _) = True<br />
nullable Empty = True<br />
nullable Void = False<br />
nullable (Var _) = False<br />
<br />
deriv :: RegExp -> Char -> RegExp<br />
deriv (Char cs) c<br />
| c `Set.member` cs = Empty<br />
| otherwise = Void<br />
deriv (Alt r1 r2) c = Alt (deriv r1 c) (deriv r2 c)<br />
deriv (Seq r1 r2) c<br />
| nullable r1 = Alt (Seq (deriv r1 c) r2) (deriv r2 c)<br />
| otherwise = Seq (deriv r1 c) r2<br />
deriv (Star r) c = deriv (Alt Empty (Seq r (Star r))) c<br />
deriv Empty _ = Void<br />
deriv Void _ = Void<br />
deriv (Var _) _ = Void<br />
</haskell><br />
<br />
The <code>RegExp</code> data type and the <hask>match</hask> function solve the initially posed problem of providing regular expressions in Haskell. However, specifying regular expressions in abstract syntax is extremely tedious. For example, consider defining a regular expression for checking the wellformedness of email addresses ending with the top level domain '''.com'''. In its usual concrete syntax, such a regular expression is easily defined as <code>([a-z]|[0-9])*@([a-z]|[0-9])*.com</code>, but writing it in terms of the <code>RegExp</code> dataype is verbose and unintuitive. Moreover, parsing functions like<br />
<br />
* <hask>compile :: String -> RegExp</hask>, or<br />
* <hask>compile' :: String -> Either CompileError RegExp</hask><br />
<br />
do not remedy the problem of working with regular expressions in concrete syntax. Due to "compiling" regular expressions at run time, they don't provide any compile-time type-safety guarantees that the input raw expression is wellformed; thus they lead to either run time exceptions for illformed regular expressions (e.g., <hask>compile</hask>) or induce a tedious handling for compiled regexes (e.g., <hask>compile'</hask>).<br />
<br />
To preserve type safety and yet to be able to use regular expressions conveniently, we want to embed the concrete regular expression syntax into the Haskell host language. This can be done via Template Haskell's quasi quotes and furthermore enabling the <code>QuasiQuotes</code> extension. This allows defining ''quasi quotes'' for regular expressions, denoted <code>[regex| .. |]</code>, where anything inside the quasi quote is considered part of an embedded regular expression language. Using quasi quotes, we can then specify the regex for email addresses from above naturally as follows:<br />
<br />
<haskell><br />
validDotComMail :: RegExp<br />
validDotComMail = [regex|([a-z]|[0-9])*@([a-z]|[0-9])*.com|]<br />
</haskell><br />
<br />
We can even compose regular expressions easily from smaller building blocks:<br />
<br />
<haskell><br />
alphaNum, validDotComMail' :: RegExp<br />
alphaNum = [regex|[a-z]|[0-9]|]<br />
validDotComMail' = [regex|${alphaNum}*@${alphaNum}*.com|]<br />
</haskell><br />
<br />
Writing <hask>${alphaNum}</hask> interpolates the regex referred to by <hask>alphaNum</hask> into the larger regex <hask>validDotComMail'</hask>. In essence, this means that we can define our own notion of splicing values from the Haskell meta language into the embedded object language of regular expressions. We can go further and even allow to run Haskell code when interpolating with <code>${..}</code>. For example, refining our wellformedness check for '''.com''' mail addresses, we might want to ensure at least one character to occur on either side of the "@" symbol:<br />
<br />
<haskell><br />
chars, validDotComMail'' :: RegExp<br />
chars = [regex|[a-z]|[A-Z]|[0-9]|[-_.]|]<br />
validDotComMail'' = [regex|${plus chars}@${plus chars}.com|]<br />
<br />
plus :: RegExp -> RegExp<br />
plus r = Seq r (Star r)<br />
</haskell><br />
<br />
Here, <hask>plus</hask> corresponds to the usual regex combinator that requires a given regex to occur at least once. Note how <hask>plus</hask> is defined as a regular Haskell function and then used ''inside'' of the embedded regex language to build the regular expression for <hask>validDotComMail''</hask>.<br />
<br />
Intuitively, a quasi quote like <code>[regex| .. |]</code> converts an embedded language's concrete syntax to Haskell code at compile-time. It is defined by a ''quasi quoter'', which is a parser for the embedded language. Its task is to parse the embedded language's syntax into a corresponding Template Haskell expression and then to splice this expression as real Haskell code in place of the quasi quote. The conversion of embedded language code to corresponding Haskell code hereby happens before typechecking the Haskell module. Hence, trying to splice in malformed embedded language fragments will raise a Haskell type error at compile-time.<br />
<br />
The quasi quoter <code>regex</code> for our embedded language of regular expressions can be defined as follows:<br />
<br />
<haskell><br />
regex :: QuasiQuoter<br />
regex = QuasiQuoter {<br />
quoteExp = compile<br />
, quotePat = notHandled "patterns"<br />
, quoteType = notHandled "types"<br />
, quoteDec = notHandled "declarations"<br />
}<br />
where notHandled things = error $<br />
things ++ " are not handled by the regex quasiquoter."<br />
<br />
compile :: String -> Q Exp<br />
compile s =<br />
case P.parse regexParser "" s of<br />
Left err -> fail (show err)<br />
Right regexp -> [e| regexp |]<br />
</haskell><br />
<br />
That is, formally a <code>QuasiQuoter</code> consists of four parsers,<br />
<br />
<haskell><br />
quoteExp :: String -> Q Exp<br />
quotePat :: String -> Q Pat<br />
quoteType :: String -> Q Type<br />
quoteDec :: String -> Q Dec<br />
</haskell><br />
<br />
to parse raw strings of the embedded language into the different categories of Haskell syntax. In this example, however, we only want to splice embedded regular expressions into the context of Haskell expressions, so we only define the <code>quoteExp</code> parser in the <code>regex</code> quasi quoter. This parser compiles an embedded regular expression given as a string into a corresponding Template Haskell expression.<br />
<br />
Compilation by the <hask>compile</hask> function proceeds in two stages: First, we parse the input string regex into a corresponding <code>RegExp</code> value. Second, we encode this <code>RegExp</code> value as a Haskell expression in Template Haskell's <code>Q Exp</code> type. It is the second step that allows us to interpolate variables (or even code) from the Haskell host language into the EDSL for regular expressions.<br />
<br />
Parsing a raw regular expression into a corresponding <code>RegExp</code> value is a routine task using (e.g.) the ''parsec'' library:<br />
<br />
<haskell><br />
regexParser :: Parsec String () RegExp<br />
regexParser = alts <* eof where<br />
atom = try var <|> char<br />
var = Var <$> (string "${" *> many1 (noneOf "}") <* P.char '}')<br />
char = charclass <|> singlechar<br />
singlechar = (Char . Set.singleton) <$> noneOf specials<br />
charclass = fmap (Char . Set.fromList) $<br />
P.char '[' *> content <* P.char ']'<br />
content = try (concat <$> many1 range)<br />
<|> many1 (noneOf specials)<br />
range = enumFromTo<br />
<$> (noneOf specials <* P.char '-')<br />
<*> noneOf specials<br />
alts = try (Alt <$> seqs <*> (P.char '|' *> alts)) <|> seqs<br />
seqs = try (Seq <$> star <*> seqs) <|> star<br />
star = try (Star <$> (atom <* P.char '*'))<br />
<|> try (Star <$> (P.char '(' *> alts <* string ")*"))<br />
<|> atom<br />
specials = "[]()*|"<br />
</haskell><br />
<br />
To represent regular expressions of type <code>RegExp</code> as Template Haskell expressions of type <code>Q Exp</code>, Template Haskell's <code>Lift</code> typeclass is used. Its method <hask>lift :: Lift a => a -> Q Exp</hask> lifts values from the Haskell meta language (e.g., a <code>RegExp</code> value) into Template Haskell's expression language (i.e., a <code>Q Exp</code> value). The <hask>lift</hask> function is implicitly invoked by quote <hask>[e| regexp |]</hask> in function <code>compile</code>.<br />
<br />
<br />
Most of the lifting is a direct encoding of the syntactic structure of the <code>RegExp</code> value; the only interesting case is when lifting the regular expression variable <hask>Var vars</hask>. In this case, we treat the words in the string <hask>vars</hask> as referring to identifiers from the Haskell host language, which we apply in a left associative manner to each other. Doing this enables interpolation of Haskell identifiers or even simple forms of Haskell expressions into our EDSL of regular expressions as shown by the regexes <hask>validDotComMail'</hask>, and <hask>validDotComMail''</hask> above.<br />
<br />
<haskell><br />
instance Lift a => Lift (Set a) where<br />
lift set = appE (varE 'Set.fromList) (lift (Set.toList set))<br />
<br />
instance Lift RegExp where<br />
-- lift :: RegExp -> Q Exp<br />
lift (Char cs) = apply 'Char [lift cs]<br />
lift (Alt r1 r2) = apply 'Alt (map lift [r1, r2])<br />
lift (Seq r1 r2) = apply 'Seq (map lift [r1, r2])<br />
lift (Star r1) = apply 'Star (map lift [r1])<br />
lift Empty = apply 'Empty []<br />
lift Void = apply 'Void []<br />
lift (Var vars) = foldl1 appE $ map (varE . mkName) (words vars)<br />
<br />
apply :: Name -> [Q Exp] -> Q Exp<br />
apply n = foldl appE (conE n)<br />
</haskell><br />
<br />
These two steps constitute the conversion of raw string regular expressions into Template Haskell expressions inside of the <hask>compile</hask> function and define the <code>regex</code> quasiquoter. Whenever we write a quasi quote like <hask>[regex| .. |]</hask> in a Haskell expression context, <hask>regex</hask>'s parser <hask>quoteExp</hask> converts the regex EDSL into a Template Haskell expression <code>Q Exp</code> and splices in the result as a wellformed <code>RegExp</code> value. This example shows how Template Haskell and quasi quotes can be used to define a type-safe, domain specific language for regular expressions.<br />
<br />
=== Shakespearean Templates ===<br />
<br />
In much the same manner as in the last example, Template Haskell and quasi quotes are used in Michael Snoyman's <code>shakespeare</code> library<ref name="shakespeare" /><ref name="shakespeare-lib" />. It defines embedded templating languages for working with the internet's web languages from within a Haskell web application. In particular, the <code>shakespeare</code> library provides the template languages ''Hamlet'', ''Cassius'', and ''Julius'' for writing embedded HTML, CSS, and Javascript code, respectively. All three templating languages internally work quite similarly to the previous example's EDSL for regular expressions: quasi quotes allow one to write HTML, CSS, or JavaScript code in concrete (though slightly modified) syntax inside of Haskell. Moreover, identifiers from the Haskell host language as well as code fragments can be interpolated into the template languages at compile-time. In the remainder we will briefly show-case the <code>shakespeare</code> library's templating language Hamlet for creating HTML documents; the other templating languages Cassius and Julius are similar.<br />
<br />
To create and output a simple web page from inside a Haskell application, the following is enough:<br />
<br />
<haskell><br />
import Data.Text<br />
import Text.Hamlet<br />
import Text.Blaze.Html.Renderer.String<br />
<br />
data Page = Home | About | Github<br />
<br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls Github _ = "https://www.github.com/bollmann"<br />
<br />
webPage :: Text -> Text -> HtmlUrl Page<br />
webPage title content = [hamlet|<br />
<html><br />
<head><br />
<title>#{Text.toUpper title}<br />
<body><br />
<h1>#{title}<br />
<div>Welcome to my Shakespearean Templates page!<br />
<hr><br />
<div>Links:<br />
<ul><br />
<a href=@{Home}>My Homepage<br />
<a href=@{About}>About me<br />
<a href=@{Github}>Check out my Github<br />
<hr><br />
<div>#{content}<br />
|]<br />
<br />
main = putStrLn $ renderHtml $<br />
webPage "Hello Shakespeare!" "Hello World!" mkUrls<br />
</haskell><br />
<br />
Running this Haskell program, outputs an HTML page as specified by the Hamlet templating language, embedded through quasi quote <hask>[hamlet| .. |]</hask> in function <hask>webPage</hask>. Hamlet closely resembles real HTML syntax, but is even more terse: instead of a closing HTML tag, Hamlet uses indentation to indicate the span of the tag. Furthermore, Hamlet allows to interpolate code or identifiers from the Haskell host language when creating an HTML template. Interpolation of Haskell code into Hamlet is done by writing <code>#{ .. }</code>. In the above example, the HTML page's title and content are interpolated from Haskell identifiers. Note particularly how in the webpage's title we uppercase the interpolated title using Haskell's <hask>Text.toUpper</hask> function ''inside'' of the Hamlet language.<br />
<br />
In addition to this standard interpolation, Hamlet can also interpolate links by writing <code>@{..}</code>. These links are specified as values of the <hask>Page</hask> data type inside the template and the <hask>mkUrls</hask> render function translates them to real URLs later. Hamlet's URL interpolation is often described as creating "type-safe URLs". One reason is that, just like with normal variable interpolation, all interpolated links have to exist and be type correct at compile-time; in this case, links must be values of the <code>Page</code> data type. Hence, as soon as a link's constructor shape is changed, the compiler statically forces us to update all references to this link as well. Furthermore, there is only one distinct place in the code to maintain or update a link's raw URL, thus minimizing the risk of dead URLs.<br />
<br />
For example, suppose we want to add more external links to our web page. We could model this fact by changing the <hask>Page</hask> data type to<br />
<br />
<haskell><br />
data Page = Home | About | External ExternalPage<br />
data ExternalPage = Github | Haskell | Reddit<br />
</haskell><br />
<br />
and, moreover, changing the <hask>mkUrls</hask> renderer function to account for the new links:<br />
<br />
<haskell><br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls (External page) _ = mkExternalUrls page<br />
<br />
mkExternalUrls :: ExternalPage -> Text<br />
mkExternalUrls Github = "https://www.github.com"<br />
mkExternalUrls Haskell = "http://www.haskell.org"<br />
mkExternalUrls Reddit = "http://www.reddit.com/r/haskell"<br />
</haskell><br />
<br />
Doing just these changes, will then cause a compile-time error in our <hask>webPage</hask> template, since we haven't updated the <hask>Github</hask> reference to our newly adjusted link structure. Hence, the compiler reminds (and in fact forces) us to update all locations in the code that used the old <hask>Github</hask> link to now use the new <hask>External Github</hask> (as well as optionally the <hask>External Haskell</hask>, etc.) links.<br />
<br />
Finally, Hamlet allows to use some control constructs like if-conditionals, for-loops, and let-bindings to embed basic business logic into a webpage's template. Michael Snoyman gives a gentle (and much more in-depth) introduction to shakespearean templates and Yesod<ref name="shakespeare" /><ref name="yesod" />.<br />
<br />
= References =<br />
<br />
<references><br />
<ref name="th1">Tim Sheard and Simon Peyton Jones. Template Meta-Programming for Haskell. SIGPLAN Not., 37(12):60-75, December 2002. URL: https://www.microsoft.com/en-us/research/publication/template-meta-programming-for-haskell/?from=http://research.microsoft.com/~simonpj/papers/meta-haskell/ </ref><br />
<ref name="th2">Tim Sheard and Simon Peyton Jones. Notes on Template Haskell, Version 2. URL: https://www.haskell.org/ghc/docs/papers/th2.ps, 2003.</ref><br />
<ref name="th3">Simon Peyton Jones. Major Proposed Revision of Template Haskell. URL: https://ghc.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposal, 2010</ref><br />
<ref name="qq">Geoffrey Mainland. Why it's nice to be quoted: Quasiquoting for Haskell. In ''Proceedings of the ACM SIGPLAN Workshop on Haskell'', Haskell '07, pages 73-82, New York, NY, USA, 2007. ACM</ref><br />
<ref name="regexp-derivs">Janusz A. Brzozowski. Derivatives of regular expressions. J. ACM, 11(4):481–494, October 1964.</ref><br />
<ref name="shakespeare">Michael Snoyman. Shakespearean Templates. URL: http://www.yesodweb.com/book/shakespearean-templates [Accessed: May 2016].</ref><br />
<ref name="shakespeare-lib">Michael Snoyman. The <code>shakespeare</code> Haskell library. URL: http://hackage.haskell.org/package/shakespeare [Accessed: May 2016].</ref><br />
<ref name="yesod">Michael Snoyman. Haskell and Yesod. URL: http://www.yesodweb.com/book-1.4 [Accessed: May 2016].</ref><br />
<ref name="dep-tys">Daniel Friedlender and Mia Indrika. Do we need Dependent Types? J. Funct. Program. 10(4):409-415, July 2000.</ref><br />
</references></div>Enoksrdhttps://wiki.haskell.org/index.php?title=A_practical_Template_Haskell_Tutorial&diff=62534A practical Template Haskell Tutorial2018-06-21T21:46:13Z<p>Enoksrd: /* Template Haskell for building Embedded Domain specific Languages (EDSLs) */ Fix syntax</p>
<hr />
<div>This tutorial explores the Glasgow Haskell Compiler's compile-time meta programming in Template Haskell. It motivates use cases for meta programming and explains the different Template Haskell features on simple toy programs. The aim is to give an overview of Template Haskell's functionality in an example-driven manner.<br />
<br />
= Introduction =<br />
<br />
Template Haskell (TH) is the standard framework for doing type-safe, compile-time meta programming in the Glasgow Haskell Compiler (GHC). It allows writing Haskell meta programs, which are evaluated at compile-time, and which produce Haskell programs as the results of their execution.<br />
<br />
Template Haskell was conceived by Tim Sheard and Simon Peyton Jones<ref name="th1" /> by drawing on the ideas of Lisp macros, but in the typed setting of Haskell. Since then, the original implementation has evolved quite a bit<ref name="th2" /><ref name="th3" />. Most notably, in 2007 Geoffrey Mainland added support for quasi quoting<ref name="qq" />, which makes the embedding of domain specific languages into the Haskell host language much easier.<br />
<br />
As it exists today, Template Haskell has two main areas of application: Haskell code generation at compile-time and facilitating the embedding of domain specific languages.<br />
<br />
As a code generator, Template Haskell empowers a user to write many, syntactically different, programs all at once by means of a single meta program. All that is needed is a uniform, algorithmic description to create the different result programs. And the meta program then precisely implements the algorithm to compute all the different result programs as its output. This proves useful for example to avoid writing the same repetitive, boilerplate code over and over again. To this end, Template Haskell is used (among many others) in the <code>aeson</code> library to automatically derive a data type's <code>ToJSON</code> and <code>FromJSON</code> instances for JSON serialization; and in the <code>lens</code> library to mechanically create a data type's lenses.<br />
<br />
As a framework for creating domain specific languages (EDSLs), Template Haskell allows a user to embed programs written in another programming language inside of a Haskell program. This enables writing parts of the program in the concrete, domain specific syntax of a different programming language. It has the benefit to think about -- and to express -- domain specific problems in the language best suited for the task. In particular, it lets a user focus on the domain specific problem and removes all additional language burdens induced by inconvenient syntax, unsuited control constructs, etc. Programs from the embedded language are parsed and translated into corresponding (but syntactically heavier) Haskell code at compile-time by Template Haskell. In this sense, (e.g.,) the shakespearean template languages from the <code>shakespeare</code> library use Template Haskell at their core. They expose succinct domain specific languages to write HTML, CSS, and Javascript code inside of a Haskell based web application.<br />
<br />
= Template Haskell by Examples =<br />
<br />
In this section, we will review the Template Haskell features to write meta programs. The first set of examples show-cases Template Haskell's potential as a code generator; the second set of examples highlights its facilities to create embedded domain specific languages (EDSLs). All examples require GHC's language extension <code>TemplateHaskell</code> to be enabled.<br />
<br />
To avoid confusion in the sequel, we distinguish between meta programs and object programs. Meta programs are the Haskell programs that run at compile-time and which generate Template Haskell object programs as the results of their execution; they are the programs that devise or manipulate other programs by some algorithmic means. Object programs, on the other hand, are the Template Haskell programs manipulated and built by the Haskell meta programs at compile-time.<br />
<br />
== Template Haskell as a Code Generator ==<br />
<br />
As an introductory example, consider Haskell's <code>Prelude</code> function <hask>curry :: ((a,b) -> c) -> a -> b -> c</hask>, which converts a function taking a pair to its curried equivalent. Unfortunately, there are no <code>Prelude</code> functions that provide the same currying functionality for functions taking arbitrary <math>n</math>-tuples. Moreover, having to write more than a few of these functions manually is, while trivial, a very repetitive and cumbersome task. Instead we wish to generate needed <hask>curry3</hask>, <hask>curry5</hask>, or <hask>curry8</hask> functions through a single meta program on demand. Template Haskell lets us do just this. The idea is to write a meta function <hask>curryN :: Int -> Q Exp</hask> which, given a number <code>n >= 1</code>, constructs the ''source code'' for an <math>n</math>-ary <hask>curry</hask> function:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import Control.Monad<br />
import Language.Haskell.TH<br />
<br />
curryN :: Int -> Q Exp<br />
curryN n = do<br />
f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
let args = map VarP (f:xs)<br />
ntup = TupE (map VarE xs)<br />
return $ LamE args (AppE (VarE f) ntup)<br />
</haskell><br />
<br />
For input <math>n</math>, meta function <hask>curryN</hask> builds a lambda abstraction <hask>LamE</hask> that pattern matches against a function <hask>f</hask> and <math>n</math> argument variables <hask>x1</hask>, <hask>x2</hask>, ..., <hask>xn</hask>; in its body, it then applies function <hask>f</hask> to the <math>n</math>-tuple <hask>(x1, x2, ..., xn)</hask> derived from the pattern matched variables. The names used to refer to the variables <hask>f</hask> and <hask>x1</hask> through <hask>xn</hask> are generated monadically by function <hask>newName :: String -> Q Name</hask> to always generate fresh names not used anywhere else. Hence, the value returned by <hask>curryN</hask> is a monadic computation of type <code>Q Exp</code>. When executed, this monadic computation yields an expression <code>Exp</code> representing the object program of an <math>n</math>-ary curry function. For example, <hask>(curryN 3)</hask> returns a monadic computation that yields an expression representing a <hask>curry3</hask> function of type <hask>((a, b, c) -> d) -> a -> b -> c -> d</hask> in abstract syntax.<ref>Note that meta function <hask>curryN</hask> cannot be written in normal Haskell per se as the type for a generated <math>n</math>-ary curry function depends on <math>n</math>. Thus, the definition of <hask>curryN</hask> requires ''dependent types'' to be expressed in Haskell, a feature not yet present. However, there already exist ingenious alternatives to "faking" dependent types in Haskell; see for instance [http://www.brics.dk/RS/01/10/ this paper] for a solution to simulate functions like <hask>curryN</hask> without dependent types).</ref><br />
<br />
<br />
To run a meta program like <hask>curryN</hask> at compile-time, we enclose it with Template Haskell's ''splice'' operator <code>$</code> by writing (e.g.,) <hask>$(curryN 3)</hask>. This evaluates the meta program <code>curryN 3</code> and puts the resulting object program <hask>\f x1 x2 x3 -> f (x1, x2, x3)</hask> in place of the splice. In general, the splice operator <code>$</code> can be applied to any monadic <code>Q</code> computation, hereby performing this computation at compile-time and inserting the resulting object program as real Haskell code. To ensure type safety, meta programs to be run are type checked beforehand to indeed yield a valid Template Haskell object program. Hence, only imported, fully-typechecked meta programs can be run via the splice operator <code>$</code>: in particular, we have to evaluate the meta program <code>$(curryN 3)</code> in a separate module to where <code>curryN</code> is defined.<br />
<br />
To generate function declarations for the first <math>n</math> curry functions, we can devise a further meta program on top of <hask>curryN</hask> as follows:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
Running <hask>$(genCurries 20)</hask> will then splice in the first 20 curry functions at compile-time, namely:<br />
<br />
<haskell><br />
curry1 = \ f x1 -> f (x1)<br />
curry2 = \ f x1 x2 -> f (x1, x2)<br />
curry3 = \ f x1 x2 x3 -> f (x1, x2, x3)<br />
curry4 = \ f x1 x2 x3 x4 -> f (x1, x2, x3, x4)<br />
...<br />
curry20 = \ f x1 x2 ... x20 -> f (x1, x2, ..., x20)<br />
</haskell><br />
<br />
Note that in this case, <hask>genCurries</hask> returns a list of top-level function declarations that bind the anonymous lambda abstractions built by <hask>curryN</hask>. Also, to name the function bindings, we use function <hask>mkName :: String -> Name</hask> instead of <hask>newName :: String -> Q Name</hask>. The reason is that here we want to generate functions <hask>curry1</hask> to <hask>curry20</hask> with exactly the prescribed names, so they can be captured and referred to from other parts of the program.<br />
<br />
Evaluating Haskell (meta) programs at compile-time and splicing in the generated object programs as regular Haskell code is the first central building block of Template Haskell. The two other core mechanisms are exhibited by the implementations of <hask>curryN</hask> and <hask>genCurries</hask>: algebraic data types and the quotation monad <code>Q</code>.<br />
<br />
First, object programs created by Template Haskell are represented as regular algebraic data types, describing a program in the form of an abstract syntax tree. The Template Haskell library provides algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> to represent Haskell's surface syntax of expressions, patterns, declarations, and types, respectively. Virtually every concrete Haskell syntactic construct has a corresponding abstract syntax constructor in one of the four ADTs. Furthermore, all Haskell identifiers are represented by the abstract <code>Name</code> data type. By representing object programs as regular algebraic data types (and thus as data), normal Haskell can be used as the meta programming language to build object programs.<br />
<br />
Second, TH object programs are built inside the quotation monad <code>Q</code>. This monad is performed by the splice operator "<code>$</code>" at compile-time as part of evaluating the meta program. In the examples so far, the <code>Q</code> monad was only needed to provide fresh identifiers with function <hask>newName :: String -> Q Name</hask> for the generated Haskell expressions. The other main feature that requires a monadic construction of object programs is ''reification'', which allows to query compile-time information during the object program's construction. We will explain reification in detail later.<br />
<br />
Thus, Template Haskell's core functionality constitutes evaluating object programs with "<code>$</code>" and building them from algebraic data types inside the quotation monad <code>Q</code>. However, constructing object programs in terms of their abstract syntax trees is quite verbose and leads to clumsy meta programs. Therefore the Template Haskell API also provides two further interfaces to build object programs more conveniently: ''syntax construction functions'' and ''quotation brackets''.<br />
<br />
Syntax construction functions directly relate to the syntax constructors from the algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> for representing Haskell code. However, they hide the monadic nature of building object programs. For example, recall our definition of the <hask>genCurries</hask> meta function from above:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
To use the object program generated by the sub call to <hask>curryN</hask> in the larger context of the returned function declaration, we have to first perform <hask>curryN</hask> and bind its result to <hask>cury</hask>. The reason is that we have to account for <hask>curryN</hask>'s generation of fresh names before we can continue. Using syntax construction functions instead of data constructors, however, abstracts from the monadic construction of <hask>genCurries</hask>, thus making its code a little shorter:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = funD name [clause [] (normalB (curryN ith)) []]<br />
where name = mkName $ "curry" ++ show ith<br />
</haskell><br />
<br />
The new <code>funD</code>, <code>clause</code>, and <code>normalB</code> functions directly correspond to the formerly used <code>FunD</code>, <code>Clause</code>, and <code>NormalB</code> constructors. The only difference lies in their types:<br />
<br />
{|<br />
|-<br />
|<hask>FunD :: Name -> [Clause] -> Dec</hask><br />
|<hask>funD :: Name -> [Q Clause] -> Q Dec</hask><br />
|-<br />
|<hask>Clause :: [Pat] -> Body -> Clause</hask><br />
|<hask>clause :: [Q Pat] -> Q Body -> Q Clause</hask><br />
|-<br />
|<hask>NormalB :: Exp -> Body</hask><br />
|<hask>normalB :: Q Exp -> Q Body</hask><br />
|}<br />
<br />
While the syntax constructors work with raw TH expressions, the syntax construction functions expect their monadic counterparts. They construct a TH object program directly in <code>Q</code>, thus freeing the API consumer from doing the monadic wrapping and unwrapping manually. For every syntax constructor, there is a corresponding monadic syntax construction function provided.<br />
<br />
On top of syntax construction functions, quotation brackets are a further shortcut for representing Haskell code. They allow to specify an object program using just regular Haskell syntax by enclosing it inside oxford brackets <code>[| .. |]</code>. That way, object programs can be specified yet much more succinctly. For example, a meta program building a Haskell expression for the identity function is still quite verbose, if expressed with either ADTs or syntax construction functions:<br />
<br />
<haskell><br />
genId :: Q Exp<br />
genId = do<br />
x <- newName "x"<br />
lamE [varP x] (varE x)<br />
</haskell><br />
<br />
Using quotation brackets, writing the same meta program can be abbreviated much further as:<br />
<br />
<haskell><br />
genId' :: Q Exp<br />
genId' = [| \x -> x |]<br />
</haskell><br />
<br />
Quotation brackets quote regular Haskell code as the corresponding object program fragments inside the <code>Q</code> monad. There are quotation brackets for quoting Haskell expressions (<code>[e| .. |]|</code>), patterns (<code>[p| .. |]</code>), declarations (<code>[d| .. |]</code>), and types (<code>[t| .. |]</code>). Writing <code>[| .. |]</code> is hereby just another way of saying <code>[e| .. |]</code>. Using quotation brackets in a sense ''lifts'' Haskell's concrete syntax into corresponding object program expressions inside the <code>Q</code> monad. By doing so, quotation brackets represent the dual of the already introduced splice operator <code>$</code>: Evaluating a meta program with "<code>$</code>" splices in the generated object program as real Haskell code; in contrast, quotation brackets <code>[| .. |]</code> turn real Haskell code into an object program. Consequently, quotation brackets and the splice operator cancel each other out. The equation <code>$([| e |]) = e</code> holds for all expressions <code>e</code> and similar equations hold for declarations, and types<ref name="th2" />.<br />
<br />
In addition, there is support for quoting Haskell (value and type) identifiers as corresponding <code>Name</code>s inside Template Haskell. This allows to refer to regular Haskell identifiers from within TH object programs. For example, writing <hask>'genId</hask> yields a TH <code>Name</code> referring to the <hask>genId</hask> identifier. Similarly, <hask>''Q</hask> gives a <code>Name</code> referring to the <code>Q</code> type identifier.<br />
<br />
=== Generic Maps ===<br />
<br />
As a second example that uses both syntax construction functions as well as quotation brackets, let's consider a meta program <hask>mapN :: Int -> Q Dec</hask> to build "generic" <hask>map</hask> functions at compile-time. Invoking <hask>$(mapN 1)</hask> should generate the well-known standard function <hask>map :: (a -> b) -> [a] -> [b]</hask>; evaluating <hask>$(mapN 2)</hask> should splice in a binary map function of type <hask>(a -> b -> c) -> [a] -> [b] -> [c]</hask>, and so on.<ref>Note that <math>n</math>-ary maps are better written using Applicative Functors and <code>ZipList</code>s, as this allows to define them first-class from within regular Haskell. For understanding Template Haskell as a code generator, this example is still useful though.</ref><br />
<br />
<haskell><br />
mapN :: Int -> Q Dec<br />
mapN n<br />
| n >= 1 = funD name [cl1, cl2]<br />
| otherwise = fail "mapN: argument n may not be <= 0."<br />
where<br />
name = mkName $ "map" ++ show n<br />
cl1 = do f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
ys <- replicateM n (newName "ys")<br />
let argPatts = varP f : consPatts<br />
consPatts = [ [p| $(varP x) : $(varP ys) |]<br />
| (x,ys) <- xs `zip` ys ]<br />
apply = foldl (\ g x -> [| $g $(varE x) |])<br />
first = apply (varE f) xs<br />
rest = apply (varE name) (f:ys)<br />
clause argPatts (normalB [| $first : $rest |]) []<br />
cl2 = clause (replicate (n+1) wildP) (normalB (conE '[])) []<br />
</haskell><br />
<br />
The implementation of <hask>mapN</hask> is very much in the spirit of meta function <hask>curryN</hask> from the first example. For instance, evaluating splice <hask>$(mapN 3)</hask> splices in the following map function at compile-time:<br />
<br />
<haskell><br />
map3 f (x:xs) (y:ys) (z:zs) = f x y z : map3 f xs ys zs<br />
map3 _ _ _ _ = []<br />
</haskell><br />
<br />
Nonetheless, meta function <hask>mapN</hask> exhibits a couple of new Template Haskell features: First, quotation brackets and splices are used in several places to abbreviate the object program construction. For example, helper definition <hask>apply</hask> used to generate <hask>map3</hask>'s body <hask>f x y z : map3 f xs ys zs</hask> shows the use of quotation brackets; it also highlights how splicing (<hask>$</hask>) and quotes (<hask>[| .. |]</hask>) cancel each other out. Second, identifier quotes (namely, <hask>'[]</hask>) are used to create an object program <code>Name</code> that refers to Haskell's built-in list constructor <hask>[]</hask>. Third, the example advertises how all three APIs for building Template Haskell object programs can be interleaved. The lowermost verbose API of building a raw TH data value inside the quotation monad <code>Q</code> can be abbreviated, where possible, with syntax constructor functions and quotation brackets.<br />
<br />
Lastly, the <hask>mapN</hask> example exemplifies how Haskell's static scoping is extended to object programs. The scoping principle for object programs is just as in normal Haskell: Identifiers are bound to their lexically enclosing binders in scope at the point the object program is ''defined''. Quotation brackets and splices don't alter static scopes, even though splices may bring an object program into scope at a location, where a conflicting closure is present. For example, consider this snippet:<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
static :: Q Exp<br />
static = [| x |]<br />
<br />
plus42 :: Int -> Int<br />
plus42 x = $static + x<br />
</haskell><br />
<br />
Here the occurrence of <hask>x</hask> in <hask>static</hask> refers to the global identifier <hask>x</hask> that is lexically in scope during its definition. Splicing in <hask>static</hask> into a different scope later where a different local <hask>x</hask> is present (i.e., <hask>plus42</hask>'s local identifier <hask>x</hask>), doesn't alter the link between <hask>static</hask>'s <hask>x</hask> and the global identifier <hask>x</hask>.<br />
<br />
The only exception to static scoping in Template Haskell are the names generated by <hask>mkName :: String -> Name</hask>. These names implement dynamic scoping and ''can'' be captured in spliced-in code. Changing the previous snippet to<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
dynamic :: Q Exp<br />
dynamic = VarE (mkName "x")<br />
<br />
times2 :: Int -> Int<br />
times2 x = $dynamic + x<br />
</haskell><br />
<br />
results in the identifier <hask>x</hask> spliced in by <hask>$dynamic</hask> to be bound to the closest <hask>x</hask> in scope. Hence, its binder is <hask>times2</hask>'s local identifier <hask>x</hask> and ''not'' the global <hask>x</hask>.<br />
<br />
=== Reification ===<br />
<br />
The final major Template Haskell feature not yet described is program ''reification''. Briefly, reification allows a meta program to query compile-time information about other program parts while constructing the object program. It allows the meta program to inspect other program pieces to answer questions such as: "what's this variable's type?", "what are the class instances of this type class?", or "which constructors does this data type have and and how do they look like?". The main use case is to generate boilerplate code which ''auto-completes'' manually written code. A prime example is to generically derive type class instances from bare data type definitions.<br />
<br />
Suppose we've defined the following polymorphic data types for representing potentially erroneous values, lists, and binary trees, respectively:<br />
<br />
<haskell><br />
data Result e a = Err e | Ok a<br />
data List a = Nil | Cons a (List a)<br />
data Tree a = Leaf a | Node (Tree a) a (Tree a)<br />
</haskell><br />
<br />
Moreover, suppose we want to derive <code>Functor</code> instances for all of these types. Deriving these instances manually is straightforward, but writing them all out by hand is quite cumbersome. Especially since writing a <code>Functor</code> instance follows the same pattern across all of the above types and in fact any type <code>T a</code>.<br />
<br />
To make a type constructor <code>T</code> an instance of <code>Functor</code>, one needs to implement method <hask>fmap :: (a -> b) -> T a -> T b</hask>. Its definition is hereby precisely determined by parametricity and the functor laws: By parametricity, all values of type <code>a</code> must be replaced according to the provided function with values of type <code>b</code>. Furthermore, by the functor laws, all other shapes of the input value of type <code>T a</code> must be preserved when transforming it to the output value of type <code>T b</code>.<br />
<br />
Meta function <hask>deriveFunctor :: Name -> Q [Dec]</hask> below implements the idea of this algorithm:<br />
<br />
<haskell><br />
data Deriving = Deriving { tyCon :: Name, tyVar :: Name }<br />
<br />
deriveFunctor :: Name -> Q [Dec]<br />
deriveFunctor ty<br />
= do (TyConI tyCon) <- reify ty<br />
(tyConName, tyVars, cs) <- case tyCon of<br />
DataD _ nm tyVars cs _ -> return (nm, tyVars, cs)<br />
NewtypeD _ nm tyVars c _ -> return (nm, tyVars, [c])<br />
_ -> fail "deriveFunctor: tyCon may not be a type synonym."<br />
<br />
let (KindedTV tyVar StarT) = last tyVars<br />
instanceType = conT ''Functor `appT`<br />
(foldl apply (conT tyConName) (init tyVars))<br />
<br />
putQ $ Deriving tyConName tyVar<br />
sequence [instanceD (return []) instanceType [genFmap cs]]<br />
where<br />
apply t (PlainTV name) = appT t (varT name)<br />
apply t (KindedTV name _) = appT t (varT name)<br />
</haskell><br />
<br />
Given the name of a type constructor (e.g. <code>Result</code>, <code>List</code>, etc.), <hask>deriveFunctor</hask> derives the code for this type constructor's <code>Functor</code> instance. For example, running the splice <hask>$(deriveFunctor ''Tree)</hask> generates the following code:<br />
<br />
<haskell><br />
instance Functor Tree where<br />
fmap f (Leaf x) = Leaf (f x)<br />
fmap f (Node l x r) = Node (fmap f l) (f x) (fmap f r)<br />
</haskell><br />
<br />
Meta function <hask>deriveFunctor</hask> shows reification in action. It calls function <hask>reify :: Name -> Q Info</hask> on the input type constructor's name to yield information about this data type's definition. Using <hask>reify</hask>, it thus learns whether the data type was defined using the <code>data</code> or <code>newtype</code> keyword, which constructors it defines and what their shapes are. Based on the learned structure, <hask>deriveFunctor</hask> is then able to generate a suitable definition of <hask>fmap</hask> and its different clauses via the auxiliaries <hask>genFmap</hask>, <hask>genFmapClause</hask>, and <hask>newField</hask>, defined below. These auxiliary definitions generate one <hask>fmap</hask> clause for each of the data type's constructors. And each clause then transforms its constructor by recursively modifying all of the constructor's fields of type <code>a</code> through <hask>fmap</hask>'s function <code>f</code>, while retaining all other shapes.<br />
<br />
<haskell><br />
genFmap :: [Con] -> Q Dec<br />
genFmap cs<br />
= do funD 'fmap (map genFmapClause cs)<br />
<br />
genFmapClause :: Con -> Q Clause<br />
genFmapClause c@(NormalC name fieldTypes)<br />
= do f <- newName "f"<br />
fieldNames <- replicateM (length fieldTypes) (newName "x")<br />
<br />
let pats = varP f:[conP name (map varP fieldNames)]<br />
body = normalB $ appsE $<br />
conE name : map (newField f) (zip fieldNames fieldTypes)<br />
<br />
clause pats body []<br />
<br />
newField :: Name -> (Name, StrictType) -> Q Exp<br />
newField f (x, (_, fieldType))<br />
= do Just (Deriving typeCon typeVar) <- getQ<br />
case fieldType of<br />
VarT typeVar' | typeVar' == typeVar -><br />
[| $(varE f) $(varE x) |]<br />
ty `AppT` VarT typeVar' |<br />
leftmost ty == (ConT typeCon) && typeVar' == typeVar -><br />
[| fmap $(varE f) $(varE x) |]<br />
_ -> [| $(varE x) |]<br />
<br />
leftmost :: Type -> Type<br />
leftmost (AppT ty1 _) = leftmost ty1<br />
leftmost ty = ty<br />
</haskell><br />
<br />
In more detail, <hask>deriveFunctor</hask> works as follows. First, via <hask>reify</hask> it observes the input data type's name <hask>tyConName</hask>, its declared type variables <hask>tyVars</hask>, and its exposed constructors <hask>cs</hask>. It then determines the data type's right-most type variable <hask>tyVar</hask> and stores it together with the data type's type constructor name <hask>tyConName</hask> in the <hask>Q</hask> monad's user state. This state information is retrieved later again from inside auxiliary definition <hask>newField</hask>. Next, <hask>deriveFunctor</hask> derives a <hask>Functor</hask>'s <hask>fmap</hask> definition using auxiliary <hask>genFmap</hask>. For each of the input data type's value constructors <hask>cs</hask>, <hask>genFmap</hask> generates an <hask>fmap</hask> clause using helper function <hask>genFmapClause</hask>. The latter recursively maps the provided function <hask>f :: a -> b</hask> over all of a constructor's fields of type <code>a</code>, while leaving all other fields untouched. Each field is hereby modified through <hask>f</hask> or left unchanged by auxiliary <hask>newField</hask> based on the field's type: if a field's type is <code>a</code> (which is stored in the retrieved <hask>tyVar</hask> inside function <hask>newField</hask>), then <hask>f</hask> needs to be applied to it; otherwise it needs to remain unchanged.<br />
<br />
<br />
In an analogous manner to <hask>deriveFunctor</hask>, a function <hask>deriveFoldable :: Name -> Q [Dec]</hask> can be devised to derive a data type's <code>Foldable</code> instance. All that is needed is to provide a definition for function <hask>foldMap :: Monoid m => (a -> m) -> T a -> m</hask>. Again, <hask>foldMap</hask>'s definition follows directly from a data type's bare definition, which can be observed by means of reification. This highlights particularly how the functionality offered by Template Haskell provides a low-level API into the GHC compiler to manipulate abstract syntax trees at compile-time. This mechanism is quite powerful and even allows to simulate some of GHC's offered language extensions, e.g., <code>-XDeriveFunctor</code> and <code>-XDeriveFoldable</code>, to be implemented as a library on top of Template Haskell.<br />
<br />
== Template Haskell for building Embedded Domain specific Languages (EDSLs) ==<br />
<br />
To see Template Haskell's potential for building an EDSL, consider the problem of pattern matching text with regular expressions. Suppose, as part of a Haskell program we need to devise many different regular expressions and use them to pattern match text fragments. Regular expressions are easily defined by an algebraic data type capturing their structure, as well as an evaluator checking whether a regular expression matches some input string. <ref>This example draws on Penn's CIS 552 ''Advanced Programming'' course, specifically Assignment 5: http://www.seas.upenn.edu/~cis552/current/hw/hw05/Main.html.</ref><br />
<br />
<haskell><br />
data RegExp<br />
= Char (Set Char) -- [a], [abc], [a-z]; matches a single character from the specified class<br />
| Alt RegExp RegExp -- r1 | r2 (alternation); matches either r1 or r2<br />
| Seq RegExp RegExp -- r1 r2 (concatenation); matches r1 followed by r2<br />
| Star RegExp -- r* (Kleene star); matches r zero or more times<br />
| Empty -- matches only the empty string<br />
| Void -- matches nothing (always fails)<br />
| Var String -- a variable holding another regexp (explained later)<br />
deriving Show<br />
<br />
match :: RegExp -> String -> Bool<br />
match r s = nullable (foldl deriv r s)<br />
</haskell><br />
<br />
The evaluator <hask>match</hask> is hereby based on the concept of derivatives<ref name="regexp-derivs" />: an initial regular expression <hask>r</hask> matches an input string <hask>s</hask>, if <hask>r</hask> matches the first character of <hask>s</hask> and its derivative regular expression <hask>(deriv r)</hask> matches the remainder of <hask>s</hask>:<br />
<br />
<haskell><br />
nullable :: RegExp -> Bool<br />
nullable (Char _) = False<br />
nullable (Alt r1 r2) = nullable r1 || nullable r2<br />
nullable (Seq r1 r2) = nullable r1 && nullable r2<br />
nullable (Star _) = True<br />
nullable Empty = True<br />
nullable Void = False<br />
nullable (Var _) = False<br />
<br />
deriv :: RegExp -> Char -> RegExp<br />
deriv (Char cs) c<br />
| c `Set.member` cs = Empty<br />
| otherwise = Void<br />
deriv (Alt r1 r2) c = Alt (deriv r1 c) (deriv r2 c)<br />
deriv (Seq r1 r2) c<br />
| nullable r1 = Alt (Seq (deriv r1 c) r2) (deriv r2 c)<br />
| otherwise = Seq (deriv r1 c) r2<br />
deriv (Star r) c = deriv (Alt Empty (Seq r (Star r))) c<br />
deriv Empty _ = Void<br />
deriv Void _ = Void<br />
deriv (Var _) _ = Void<br />
</haskell><br />
<br />
The <code>RegExp</code> data type and the <hask>match</hask> function solve the initially posed problem of providing regular expressions in Haskell. However, specifying regular expressions in abstract syntax is extremely tedious. For example, consider defining a regular expression for checking the wellformedness of email addresses ending with the top level domain '''.com'''. In its usual concrete syntax, such a regular expression is easily defined as <code>([a-z]|[0-9])*@([a-z]|[0-9])*.com</code>, but writing it in terms of the <code>RegExp</code> dataype is verbose and unintuitive. Moreover, parsing functions like<br />
<br />
* <hask>compile :: String -> RegExp</hask>, or<br />
* <hask>compile' :: String -> Either CompileError RegExp</hask><br />
<br />
do not remedy the problem of working with regular expressions in concrete syntax. Due to "compiling" regular expressions at run time, they don't provide any compile-time type-safety guarantees that the input raw expression is wellformed; thus they lead to either run time exceptions for illformed regular expressions (e.g., <hask>compile</hask>) or induce a tedious handling for compiled regexes (e.g., <hask>compile'</hask>).<br />
<br />
To preserve type safety and yet to be able to use regular expressions conveniently, we want to embed the concrete regular expression syntax into the Haskell host language. This can be done via Template Haskell's quasi quotes and furthermore enabling the <code>QuasiQuotes</code> extension. This allows defining ''quasi quotes'' for regular expressions, denoted <code>[regex| .. |]</code>, where anything inside the quasi quote is considered part of an embedded regular expression language. Using quasi quotes, we can then specify the regex for email addresses from above naturally as follows:<br />
<br />
<haskell><br />
validDotComMail :: RegExp<br />
validDotComMail = [regex|([a-z]|[0-9])*@([a-z]|[0-9])*.com|]<br />
</haskell><br />
<br />
We can even compose regular expressions easily from smaller building blocks:<br />
<br />
<haskell><br />
alphaNum, validDotComMail' :: RegExp<br />
alphaNum = [regex|[a-z]|[0-9]|]<br />
validDotComMail' = [regex|${alphaNum}*@${alphaNum}*.com|]<br />
</haskell><br />
<br />
Writing <hask>${alphaNum}</hask> interpolates the regex referred to by <hask>alphaNum</hask> into the larger regex <hask>validDotComMail'</hask>. In essence, this means that we can define our own notion of splicing values from the Haskell meta language into the embedded object language of regular expressions. We can go further and even allow to run Haskell code when interpolating with <code>${..}</code>. For example, refining our wellformedness check for '''.com''' mail addresses, we might want to ensure at least one character to occur on either side of the "@" symbol:<br />
<br />
<haskell><br />
chars, validDotComMail'' :: RegExp<br />
chars = [regex|[a-z]|[A-Z]|[0-9]|[-_.]|]<br />
validDotComMail'' = [regex|${plus chars}@${plus chars}.com|]<br />
<br />
plus :: RegExp -> RegExp<br />
plus r = Seq r (Star r)<br />
</haskell><br />
<br />
Here, <hask>plus</hask> corresponds to the usual regex combinator that requires a given regex to occur at least once. Note how <hask>plus</hask> is defined as a regular Haskell function and then used ''inside'' of the embedded regex language to build the regular expression for <hask>validDotComMail''</hask>.<br />
<br />
Intuitively, a quasi quote like <code>[regex| .. |]</code> converts an embedded language's concrete syntax to Haskell code at compile-time. It is defined by a ''quasi quoter'', which is a parser for the embedded language. Its task is to parse the embedded language's syntax into a corresponding Template Haskell expression and then to splice this expression as real Haskell code in place of the quasi quote. The conversion of embedded language code to corresponding Haskell code hereby happens before typechecking the Haskell module. Hence, trying to splice in malformed embedded language fragments will raise a Haskell type error at compile-time.<br />
<br />
The quasi quoter <code>regex</code> for our embedded language of regular expressions can be defined as follows:<br />
<br />
<haskell><br />
regex :: QuasiQuoter<br />
regex = QuasiQuoter {<br />
quoteExp = compile<br />
, quotePat = notHandled "patterns"<br />
, quoteType = notHandled "types"<br />
, quoteDec = notHandled "declarations"<br />
}<br />
where notHandled things = error $<br />
things ++ " are not handled by the regex quasiquoter."<br />
<br />
compile :: String -> Q Exp<br />
compile s =<br />
case P.parse regexParser "" s of<br />
Left err -> fail (show err)<br />
Right regexp -> [e| regexp |]<br />
</haskell><br />
<br />
That is, formally a <code>QuasiQuoter</code> consists of four parsers,<br />
<br />
<haskell><br />
quoteExp :: String -> Q Exp<br />
quotePat :: String -> Q Pat<br />
quoteType :: String -> Q Type<br />
quoteDec :: String -> Q Dec<br />
</haskell><br />
<br />
to parse raw strings of the embedded language into the different categories of Haskell syntax. In this example, however, we only want to splice embedded regular expressions into the context of Haskell expressions, so we only define the <code>quoteExp</code> parser in the <code>regex</code> quasi quoter. This parser compiles an embedded regular expression given as a string into a corresponding Template Haskell expression.<br />
<br />
Compilation by the <hask>compile</hask> function proceeds in two stages: First, we parse the input string regex into a corresponding <code>RegExp</code> value. Second, we encode this <code>RegExp</code> value as a Haskell expression in Template Haskell's <code>Q Exp</code> type. It is the second step that allows us to interpolate variables (or even code) from the Haskell host language into the EDSL for regular expressions.<br />
<br />
Parsing a raw regular expression into a corresponding <code>RegExp</code> value is a routine task using (e.g.) the ''parsec'' library:<br />
<br />
<haskell><br />
regexParser :: Parsec String () RegExp<br />
regexParser = alts <* eof where<br />
atom = try var <|> char<br />
var = Var <$> (string "${" *> many1 (noneOf "}") <* P.char '}')<br />
char = charclass <|> singlechar<br />
singlechar = (Char . Set.singleton) <$> noneOf specials<br />
charclass = fmap (Char . Set.fromList) $<br />
P.char '[' *> content <* P.char ']'<br />
content = try (concat <$> many1 range)<br />
<|> many1 (noneOf specials)<br />
range = enumFromTo<br />
<$> (noneOf specials <* P.char '-')<br />
<*> noneOf specials<br />
alts = try (Alt <$> seqs <*> (P.char '|' *> alts)) <|> seqs<br />
seqs = try (Seq <$> star <*> seqs) <|> star<br />
star = try (Star <$> (atom <* P.char '*'))<br />
<|> try (Star <$> (P.char '(' *> alts <* string ")*"))<br />
<|> atom<br />
specials = "[]()*|"<br />
</haskell><br />
<br />
To represent regular expressions of type <code>RegExp</code> as Template Haskell expressions of type <code>Q Exp</code>, Template Haskell's <code>Lift</code> typeclass is used. Its method <hask>lift :: Lift a => a -> Q Exp</hask> lifts values from the Haskell meta language (e.g., a <code>RegExp</code> value) into Template Haskell's expression language (i.e., a <code>Q Exp</code> value). The <hask>lift</hask> function is implicitly invoked by quote <hask>[e| regexp |]</hask> in function <code>compile</code>.<br />
<br />
<br />
Most of the lifting is a direct encoding of the syntactic structure of the <code>RegExp</code> value; the only interesting case is when lifting the regular expression variable <hask>Var vars</hask>. In this case, we treat the words in the string <hask>vars</hask> as referring to identifiers from the Haskell host language, which we apply in a left associative manner to each other. Doing this enables interpolation of Haskell identifiers or even simple forms of Haskell expressions into our EDSL of regular expressions as shown by the regexes <hask>validDotComMail'</hask>, and <hask>validDotComMail''</hask> above.<br />
<br />
<haskell><br />
instance Lift a => Lift (Set a) where<br />
lift set = appE (varE 'Set.fromList) (lift (Set.toList set))<br />
<br />
instance Lift RegExp where<br />
-- lift :: RegExp -> Q Exp<br />
lift (Char cs) = apply 'Char [lift cs]<br />
lift (Alt r1 r2) = apply 'Alt (map lift [r1, r2])<br />
lift (Seq r1 r2) = apply 'Seq (map lift [r1, r2])<br />
lift (Star r1) = apply 'Star (map lift [r1])<br />
lift Empty = apply 'Empty []<br />
lift Void = apply 'Void []<br />
lift (Var vars) = foldl1 appE $ map (varE . mkName) (words vars)<br />
<br />
apply :: Name -> [Q Exp] -> Q Exp<br />
apply n = foldl appE (conE n)<br />
</haskell><br />
<br />
These two steps constitute the conversion of raw string regular expressions into Template Haskell expressions inside of the <hask>compile</hask> function and define the <code>regex</code> quasiquoter. Whenever we write a quasi quote like <hask>[regex| .. |]</hask> in a Haskell expression context, <hask>regex</hask>'s parser <hask>quoteExp</hask> converts the regex EDSL into a Template Haskell expression <code>Q Exp</code> and splices in the result as a wellformed <code>RegExp</code> value. This example shows how Template Haskell and quasi quotes can be used to define a type-safe, domain specific language for regular expressions.<br />
<br />
=== Shakespearean Templates ===<br />
<br />
In much the same manner as in the last example, Template Haskell and quasi quotes are used in Michael Snoyman's <code>shakespeare</code> library<ref name="shakespeare" /><ref name="shakespeare-lib" />. It defines embedded templating languages for working with the internet's web languages from within a Haskell web application. In particular, the <code>shakespeare</code> library provides the template languages ''Hamlet'', ''Cassius'', and ''Julius'' for writing embedded HTML, CSS, and Javascript code, respectively. All three templating languages internally work quite similarly to the previous example's EDSL for regular expressions: quasi quotes allow one to write HTML, CSS, or JavaScript code in concrete (though slightly modified) syntax inside of Haskell. Moreover, identifiers from the Haskell host language as well as code fragments can be interpolated into the template languages at compile-time. In the remainder we will briefly show-case the <code>shakespeare</code> library's templating language Hamlet for creating HTML documents; the other templating languages Cassius and Julius are similar.<br />
<br />
To create and output a simple web page from inside a Haskell application, the following is enough:<br />
<br />
<haskell><br />
import Data.Text<br />
import Text.Hamlet<br />
import Text.Blaze.Html.Renderer.String<br />
<br />
data Page = Home | About | Github<br />
<br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls Github _ = "https://www.github.com/bollmann"<br />
<br />
webPage :: Text -> Text -> HtmlUrl Page<br />
webPage title content = [hamlet|<br />
<html><br />
<head><br />
<title>#{Text.toUpper title}<br />
<body><br />
<h1>#{title}<br />
<div>Welcome to my Shakespearean Templates page!<br />
<hr><br />
<div>Links:<br />
<ul><br />
<a href=@{Home}>My Homepage<br />
<a href=@{About}>About me<br />
<a href=@{Github}>Check out my Github<br />
<hr><br />
<div>#{content}<br />
|]<br />
<br />
main = putStrLn $ renderHtml $<br />
webPage "Hello Shakespeare!" "Hello World!" mkUrls<br />
</haskell><br />
<br />
Running this Haskell program, outputs an HTML page as specified by the Hamlet templating language, embedded through quasi quote <hask>[hamlet| .. |]</hask> in function <hask>webPage</hask>. Hamlet closely resembles real HTML syntax, but is even more terse: instead of a closing HTML tag, Hamlet uses indentation to indicate the span of the tag. Furthermore, Hamlet allows to interpolate code or identifiers from the Haskell host language when creating an HTML template. Interpolation of Haskell code into Hamlet is done by writing <code>#{ .. }</code>. In the above example, the HTML page's title and content are interpolated from Haskell identifiers. Note particularly how in the webpage's title we uppercase the interpolated title using Haskell's <hask>Text.toUpper</hask> function ''inside'' of the Hamlet language.<br />
<br />
In addition to this standard interpolation, Hamlet can also interpolate links by writing <code>@{..}</code>. These links are specified as values of the <hask>Page</hask> data type inside the template and the <hask>mkUrls</hask> render function translates them to real URLs later. Hamlet's URL interpolation has commonly be phrased as creating "type-safe URLs". One reason is that, just like with normal variable interpolation, all interpolated links have to exist and be type correct at compile-time; in this case, links must be values of the <code>Page</code> data type. Hence, as soon as a link's constructor shape is changed, the compiler statically forces us to update all references to this link as well. Furthermore, there is only one distinct place in the code to maintain or update a link's raw URL, thus minimizing the risk of dead URLs.<br />
<br />
For example, suppose we want to add more external links to our web page. We could model this fact by changing the <hask>Page</hask> data type to<br />
<br />
<haskell><br />
data Page = Home | About | External ExternalPage<br />
data ExternalPage = Github | Haskell | Reddit<br />
</haskell><br />
<br />
and, moreover, changing the <hask>mkUrls</hask> renderer function to account for the new links:<br />
<br />
<haskell><br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls (External page) _ = mkExternalUrls page<br />
<br />
mkExternalUrls :: ExternalPage -> Text<br />
mkExternalUrls Github = "https://www.github.com"<br />
mkExternalUrls Haskell = "http://www.haskell.org"<br />
mkExternalUrls Reddit = "http://www.reddit.com/r/haskell"<br />
</haskell><br />
<br />
Doing just these changes, will then cause a compile-time error in our <hask>webPage</hask> template, since we haven't updated the <hask>Github</hask> reference to our newly adjusted link structure. Hence, the compiler reminds (and in fact forces) us to update all locations in the code that used the old <hask>Github</hask> link to now use the new <hask>External Github</hask> (as well as optionally the <hask>External Haskell</hask>, etc.) links.<br />
<br />
Finally, Hamlet allows to use some control constructs like if conditionals, for loops, and let bindings to embed basic business logic into a webpage's template. Michael Snoyman gives a gentle (and much more in-depth) introduction to shakespearean templates and Yesod<ref name="shakespeare" /><ref name="yesod" />.<br />
<br />
= References =<br />
<br />
<references><br />
<ref name="th1">Tim Sheard and Simon Peyton Jones. Template Meta-Programming for Haskell. SIGPLAN Not., 37(12):60-75, December 2002. URL: https://www.microsoft.com/en-us/research/publication/template-meta-programming-for-haskell/?from=http://research.microsoft.com/~simonpj/papers/meta-haskell/ </ref><br />
<ref name="th2">Tim Sheard and Simon Peyton Jones. Notes on Template Haskell, Version 2. URL: https://www.haskell.org/ghc/docs/papers/th2.ps, 2003.</ref><br />
<ref name="th3">Simon Peyton Jones. Major Proposed Revision of Template Haskell. URL: https://ghc.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposal, 2010</ref><br />
<ref name="qq">Geoffrey Mainland. Why it's nice to be quoted: Quasiquoting for Haskell. In ''Proceedings of the ACM SIGPLAN Workshop on Haskell'', Haskell '07, pages 73-82, New York, NY, USA, 2007. ACM</ref><br />
<ref name="regexp-derivs">Janusz A. Brzozowski. Derivatives of regular expressions. J. ACM, 11(4):481–494, October 1964.</ref><br />
<ref name="shakespeare">Michael Snoyman. Shakespearean Templates. URL: http://www.yesodweb.com/book/shakespearean-templates [Accessed: May 2016].</ref><br />
<ref name="shakespeare-lib">Michael Snoyman. The <code>shakespeare</code> Haskell library. URL: http://hackage.haskell.org/package/shakespeare [Accessed: May 2016].</ref><br />
<ref name="yesod">Michael Snoyman. Haskell and Yesod. URL: http://www.yesodweb.com/book-1.4 [Accessed: May 2016].</ref><br />
<ref name="dep-tys">Daniel Friedlender and Mia Indrika. Do we need Dependent Types? J. Funct. Program. 10(4):409-415, July 2000.</ref><br />
</references></div>Enoksrdhttps://wiki.haskell.org/index.php?title=A_practical_Template_Haskell_Tutorial&diff=62533A practical Template Haskell Tutorial2018-06-21T21:10:13Z<p>Enoksrd: /* Reification */ Fix syntax</p>
<hr />
<div>This tutorial explores the Glasgow Haskell Compiler's compile-time meta programming in Template Haskell. It motivates use cases for meta programming and explains the different Template Haskell features on simple toy programs. The aim is to give an overview of Template Haskell's functionality in an example-driven manner.<br />
<br />
= Introduction =<br />
<br />
Template Haskell (TH) is the standard framework for doing type-safe, compile-time meta programming in the Glasgow Haskell Compiler (GHC). It allows writing Haskell meta programs, which are evaluated at compile-time, and which produce Haskell programs as the results of their execution.<br />
<br />
Template Haskell was conceived by Tim Sheard and Simon Peyton Jones<ref name="th1" /> by drawing on the ideas of Lisp macros, but in the typed setting of Haskell. Since then, the original implementation has evolved quite a bit<ref name="th2" /><ref name="th3" />. Most notably, in 2007 Geoffrey Mainland added support for quasi quoting<ref name="qq" />, which makes the embedding of domain specific languages into the Haskell host language much easier.<br />
<br />
As it exists today, Template Haskell has two main areas of application: Haskell code generation at compile-time and facilitating the embedding of domain specific languages.<br />
<br />
As a code generator, Template Haskell empowers a user to write many, syntactically different, programs all at once by means of a single meta program. All that is needed is a uniform, algorithmic description to create the different result programs. And the meta program then precisely implements the algorithm to compute all the different result programs as its output. This proves useful for example to avoid writing the same repetitive, boilerplate code over and over again. To this end, Template Haskell is used (among many others) in the <code>aeson</code> library to automatically derive a data type's <code>ToJSON</code> and <code>FromJSON</code> instances for JSON serialization; and in the <code>lens</code> library to mechanically create a data type's lenses.<br />
<br />
As a framework for creating domain specific languages (EDSLs), Template Haskell allows a user to embed programs written in another programming language inside of a Haskell program. This enables writing parts of the program in the concrete, domain specific syntax of a different programming language. It has the benefit to think about -- and to express -- domain specific problems in the language best suited for the task. In particular, it lets a user focus on the domain specific problem and removes all additional language burdens induced by inconvenient syntax, unsuited control constructs, etc. Programs from the embedded language are parsed and translated into corresponding (but syntactically heavier) Haskell code at compile-time by Template Haskell. In this sense, (e.g.,) the shakespearean template languages from the <code>shakespeare</code> library use Template Haskell at their core. They expose succinct domain specific languages to write HTML, CSS, and Javascript code inside of a Haskell based web application.<br />
<br />
= Template Haskell by Examples =<br />
<br />
In this section, we will review the Template Haskell features to write meta programs. The first set of examples show-cases Template Haskell's potential as a code generator; the second set of examples highlights its facilities to create embedded domain specific languages (EDSLs). All examples require GHC's language extension <code>TemplateHaskell</code> to be enabled.<br />
<br />
To avoid confusion in the sequel, we distinguish between meta programs and object programs. Meta programs are the Haskell programs that run at compile-time and which generate Template Haskell object programs as the results of their execution; they are the programs that devise or manipulate other programs by some algorithmic means. Object programs, on the other hand, are the Template Haskell programs manipulated and built by the Haskell meta programs at compile-time.<br />
<br />
== Template Haskell as a Code Generator ==<br />
<br />
As an introductory example, consider Haskell's <code>Prelude</code> function <hask>curry :: ((a,b) -> c) -> a -> b -> c</hask>, which converts a function taking a pair to its curried equivalent. Unfortunately, there are no <code>Prelude</code> functions that provide the same currying functionality for functions taking arbitrary <math>n</math>-tuples. Moreover, having to write more than a few of these functions manually is, while trivial, a very repetitive and cumbersome task. Instead we wish to generate needed <hask>curry3</hask>, <hask>curry5</hask>, or <hask>curry8</hask> functions through a single meta program on demand. Template Haskell lets us do just this. The idea is to write a meta function <hask>curryN :: Int -> Q Exp</hask> which, given a number <code>n >= 1</code>, constructs the ''source code'' for an <math>n</math>-ary <hask>curry</hask> function:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import Control.Monad<br />
import Language.Haskell.TH<br />
<br />
curryN :: Int -> Q Exp<br />
curryN n = do<br />
f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
let args = map VarP (f:xs)<br />
ntup = TupE (map VarE xs)<br />
return $ LamE args (AppE (VarE f) ntup)<br />
</haskell><br />
<br />
For input <math>n</math>, meta function <hask>curryN</hask> builds a lambda abstraction <hask>LamE</hask> that pattern matches against a function <hask>f</hask> and <math>n</math> argument variables <hask>x1</hask>, <hask>x2</hask>, ..., <hask>xn</hask>; in its body, it then applies function <hask>f</hask> to the <math>n</math>-tuple <hask>(x1, x2, ..., xn)</hask> derived from the pattern matched variables. The names used to refer to the variables <hask>f</hask> and <hask>x1</hask> through <hask>xn</hask> are generated monadically by function <hask>newName :: String -> Q Name</hask> to always generate fresh names not used anywhere else. Hence, the value returned by <hask>curryN</hask> is a monadic computation of type <code>Q Exp</code>. When executed, this monadic computation yields an expression <code>Exp</code> representing the object program of an <math>n</math>-ary curry function. For example, <hask>(curryN 3)</hask> returns a monadic computation that yields an expression representing a <hask>curry3</hask> function of type <hask>((a, b, c) -> d) -> a -> b -> c -> d</hask> in abstract syntax.<ref>Note that meta function <hask>curryN</hask> cannot be written in normal Haskell per se as the type for a generated <math>n</math>-ary curry function depends on <math>n</math>. Thus, the definition of <hask>curryN</hask> requires ''dependent types'' to be expressed in Haskell, a feature not yet present. However, there already exist ingenious alternatives to "faking" dependent types in Haskell; see for instance [http://www.brics.dk/RS/01/10/ this paper] for a solution to simulate functions like <hask>curryN</hask> without dependent types).</ref><br />
<br />
<br />
To run a meta program like <hask>curryN</hask> at compile-time, we enclose it with Template Haskell's ''splice'' operator <code>$</code> by writing (e.g.,) <hask>$(curryN 3)</hask>. This evaluates the meta program <code>curryN 3</code> and puts the resulting object program <hask>\f x1 x2 x3 -> f (x1, x2, x3)</hask> in place of the splice. In general, the splice operator <code>$</code> can be applied to any monadic <code>Q</code> computation, hereby performing this computation at compile-time and inserting the resulting object program as real Haskell code. To ensure type safety, meta programs to be run are type checked beforehand to indeed yield a valid Template Haskell object program. Hence, only imported, fully-typechecked meta programs can be run via the splice operator <code>$</code>: in particular, we have to evaluate the meta program <code>$(curryN 3)</code> in a separate module to where <code>curryN</code> is defined.<br />
<br />
To generate function declarations for the first <math>n</math> curry functions, we can devise a further meta program on top of <hask>curryN</hask> as follows:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
Running <hask>$(genCurries 20)</hask> will then splice in the first 20 curry functions at compile-time, namely:<br />
<br />
<haskell><br />
curry1 = \ f x1 -> f (x1)<br />
curry2 = \ f x1 x2 -> f (x1, x2)<br />
curry3 = \ f x1 x2 x3 -> f (x1, x2, x3)<br />
curry4 = \ f x1 x2 x3 x4 -> f (x1, x2, x3, x4)<br />
...<br />
curry20 = \ f x1 x2 ... x20 -> f (x1, x2, ..., x20)<br />
</haskell><br />
<br />
Note that in this case, <hask>genCurries</hask> returns a list of top-level function declarations that bind the anonymous lambda abstractions built by <hask>curryN</hask>. Also, to name the function bindings, we use function <hask>mkName :: String -> Name</hask> instead of <hask>newName :: String -> Q Name</hask>. The reason is that here we want to generate functions <hask>curry1</hask> to <hask>curry20</hask> with exactly the prescribed names, so they can be captured and referred to from other parts of the program.<br />
<br />
Evaluating Haskell (meta) programs at compile-time and splicing in the generated object programs as regular Haskell code is the first central building block of Template Haskell. The two other core mechanisms are exhibited by the implementations of <hask>curryN</hask> and <hask>genCurries</hask>: algebraic data types and the quotation monad <code>Q</code>.<br />
<br />
First, object programs created by Template Haskell are represented as regular algebraic data types, describing a program in the form of an abstract syntax tree. The Template Haskell library provides algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> to represent Haskell's surface syntax of expressions, patterns, declarations, and types, respectively. Virtually every concrete Haskell syntactic construct has a corresponding abstract syntax constructor in one of the four ADTs. Furthermore, all Haskell identifiers are represented by the abstract <code>Name</code> data type. By representing object programs as regular algebraic data types (and thus as data), normal Haskell can be used as the meta programming language to build object programs.<br />
<br />
Second, TH object programs are built inside the quotation monad <code>Q</code>. This monad is performed by the splice operator "<code>$</code>" at compile-time as part of evaluating the meta program. In the examples so far, the <code>Q</code> monad was only needed to provide fresh identifiers with function <hask>newName :: String -> Q Name</hask> for the generated Haskell expressions. The other main feature that requires a monadic construction of object programs is ''reification'', which allows to query compile-time information during the object program's construction. We will explain reification in detail later.<br />
<br />
Thus, Template Haskell's core functionality constitutes evaluating object programs with "<code>$</code>" and building them from algebraic data types inside the quotation monad <code>Q</code>. However, constructing object programs in terms of their abstract syntax trees is quite verbose and leads to clumsy meta programs. Therefore the Template Haskell API also provides two further interfaces to build object programs more conveniently: ''syntax construction functions'' and ''quotation brackets''.<br />
<br />
Syntax construction functions directly relate to the syntax constructors from the algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> for representing Haskell code. However, they hide the monadic nature of building object programs. For example, recall our definition of the <hask>genCurries</hask> meta function from above:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
To use the object program generated by the sub call to <hask>curryN</hask> in the larger context of the returned function declaration, we have to first perform <hask>curryN</hask> and bind its result to <hask>cury</hask>. The reason is that we have to account for <hask>curryN</hask>'s generation of fresh names before we can continue. Using syntax construction functions instead of data constructors, however, abstracts from the monadic construction of <hask>genCurries</hask>, thus making its code a little shorter:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = funD name [clause [] (normalB (curryN ith)) []]<br />
where name = mkName $ "curry" ++ show ith<br />
</haskell><br />
<br />
The new <code>funD</code>, <code>clause</code>, and <code>normalB</code> functions directly correspond to the formerly used <code>FunD</code>, <code>Clause</code>, and <code>NormalB</code> constructors. The only difference lies in their types:<br />
<br />
{|<br />
|-<br />
|<hask>FunD :: Name -> [Clause] -> Dec</hask><br />
|<hask>funD :: Name -> [Q Clause] -> Q Dec</hask><br />
|-<br />
|<hask>Clause :: [Pat] -> Body -> Clause</hask><br />
|<hask>clause :: [Q Pat] -> Q Body -> Q Clause</hask><br />
|-<br />
|<hask>NormalB :: Exp -> Body</hask><br />
|<hask>normalB :: Q Exp -> Q Body</hask><br />
|}<br />
<br />
While the syntax constructors work with raw TH expressions, the syntax construction functions expect their monadic counterparts. They construct a TH object program directly in <code>Q</code>, thus freeing the API consumer from doing the monadic wrapping and unwrapping manually. For every syntax constructor, there is a corresponding monadic syntax construction function provided.<br />
<br />
On top of syntax construction functions, quotation brackets are a further shortcut for representing Haskell code. They allow to specify an object program using just regular Haskell syntax by enclosing it inside oxford brackets <code>[| .. |]</code>. That way, object programs can be specified yet much more succinctly. For example, a meta program building a Haskell expression for the identity function is still quite verbose, if expressed with either ADTs or syntax construction functions:<br />
<br />
<haskell><br />
genId :: Q Exp<br />
genId = do<br />
x <- newName "x"<br />
lamE [varP x] (varE x)<br />
</haskell><br />
<br />
Using quotation brackets, writing the same meta program can be abbreviated much further as:<br />
<br />
<haskell><br />
genId' :: Q Exp<br />
genId' = [| \x -> x |]<br />
</haskell><br />
<br />
Quotation brackets quote regular Haskell code as the corresponding object program fragments inside the <code>Q</code> monad. There are quotation brackets for quoting Haskell expressions (<code>[e| .. |]|</code>), patterns (<code>[p| .. |]</code>), declarations (<code>[d| .. |]</code>), and types (<code>[t| .. |]</code>). Writing <code>[| .. |]</code> is hereby just another way of saying <code>[e| .. |]</code>. Using quotation brackets in a sense ''lifts'' Haskell's concrete syntax into corresponding object program expressions inside the <code>Q</code> monad. By doing so, quotation brackets represent the dual of the already introduced splice operator <code>$</code>: Evaluating a meta program with "<code>$</code>" splices in the generated object program as real Haskell code; in contrast, quotation brackets <code>[| .. |]</code> turn real Haskell code into an object program. Consequently, quotation brackets and the splice operator cancel each other out. The equation <code>$([| e |]) = e</code> holds for all expressions <code>e</code> and similar equations hold for declarations, and types<ref name="th2" />.<br />
<br />
In addition, there is support for quoting Haskell (value and type) identifiers as corresponding <code>Name</code>s inside Template Haskell. This allows to refer to regular Haskell identifiers from within TH object programs. For example, writing <hask>'genId</hask> yields a TH <code>Name</code> referring to the <hask>genId</hask> identifier. Similarly, <hask>''Q</hask> gives a <code>Name</code> referring to the <code>Q</code> type identifier.<br />
<br />
=== Generic Maps ===<br />
<br />
As a second example that uses both syntax construction functions as well as quotation brackets, let's consider a meta program <hask>mapN :: Int -> Q Dec</hask> to build "generic" <hask>map</hask> functions at compile-time. Invoking <hask>$(mapN 1)</hask> should generate the well-known standard function <hask>map :: (a -> b) -> [a] -> [b]</hask>; evaluating <hask>$(mapN 2)</hask> should splice in a binary map function of type <hask>(a -> b -> c) -> [a] -> [b] -> [c]</hask>, and so on.<ref>Note that <math>n</math>-ary maps are better written using Applicative Functors and <code>ZipList</code>s, as this allows to define them first-class from within regular Haskell. For understanding Template Haskell as a code generator, this example is still useful though.</ref><br />
<br />
<haskell><br />
mapN :: Int -> Q Dec<br />
mapN n<br />
| n >= 1 = funD name [cl1, cl2]<br />
| otherwise = fail "mapN: argument n may not be <= 0."<br />
where<br />
name = mkName $ "map" ++ show n<br />
cl1 = do f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
ys <- replicateM n (newName "ys")<br />
let argPatts = varP f : consPatts<br />
consPatts = [ [p| $(varP x) : $(varP ys) |]<br />
| (x,ys) <- xs `zip` ys ]<br />
apply = foldl (\ g x -> [| $g $(varE x) |])<br />
first = apply (varE f) xs<br />
rest = apply (varE name) (f:ys)<br />
clause argPatts (normalB [| $first : $rest |]) []<br />
cl2 = clause (replicate (n+1) wildP) (normalB (conE '[])) []<br />
</haskell><br />
<br />
The implementation of <hask>mapN</hask> is very much in the spirit of meta function <hask>curryN</hask> from the first example. For instance, evaluating splice <hask>$(mapN 3)</hask> splices in the following map function at compile-time:<br />
<br />
<haskell><br />
map3 f (x:xs) (y:ys) (z:zs) = f x y z : map3 f xs ys zs<br />
map3 _ _ _ _ = []<br />
</haskell><br />
<br />
Nonetheless, meta function <hask>mapN</hask> exhibits a couple of new Template Haskell features: First, quotation brackets and splices are used in several places to abbreviate the object program construction. For example, helper definition <hask>apply</hask> used to generate <hask>map3</hask>'s body <hask>f x y z : map3 f xs ys zs</hask> shows the use of quotation brackets; it also highlights how splicing (<hask>$</hask>) and quotes (<hask>[| .. |]</hask>) cancel each other out. Second, identifier quotes (namely, <hask>'[]</hask>) are used to create an object program <code>Name</code> that refers to Haskell's built-in list constructor <hask>[]</hask>. Third, the example advertises how all three APIs for building Template Haskell object programs can be interleaved. The lowermost verbose API of building a raw TH data value inside the quotation monad <code>Q</code> can be abbreviated, where possible, with syntax constructor functions and quotation brackets.<br />
<br />
Lastly, the <hask>mapN</hask> example exemplifies how Haskell's static scoping is extended to object programs. The scoping principle for object programs is just as in normal Haskell: Identifiers are bound to their lexically enclosing binders in scope at the point the object program is ''defined''. Quotation brackets and splices don't alter static scopes, even though splices may bring an object program into scope at a location, where a conflicting closure is present. For example, consider this snippet:<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
static :: Q Exp<br />
static = [| x |]<br />
<br />
plus42 :: Int -> Int<br />
plus42 x = $static + x<br />
</haskell><br />
<br />
Here the occurrence of <hask>x</hask> in <hask>static</hask> refers to the global identifier <hask>x</hask> that is lexically in scope during its definition. Splicing in <hask>static</hask> into a different scope later where a different local <hask>x</hask> is present (i.e., <hask>plus42</hask>'s local identifier <hask>x</hask>), doesn't alter the link between <hask>static</hask>'s <hask>x</hask> and the global identifier <hask>x</hask>.<br />
<br />
The only exception to static scoping in Template Haskell are the names generated by <hask>mkName :: String -> Name</hask>. These names implement dynamic scoping and ''can'' be captured in spliced-in code. Changing the previous snippet to<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
dynamic :: Q Exp<br />
dynamic = VarE (mkName "x")<br />
<br />
times2 :: Int -> Int<br />
times2 x = $dynamic + x<br />
</haskell><br />
<br />
results in the identifier <hask>x</hask> spliced in by <hask>$dynamic</hask> to be bound to the closest <hask>x</hask> in scope. Hence, its binder is <hask>times2</hask>'s local identifier <hask>x</hask> and ''not'' the global <hask>x</hask>.<br />
<br />
=== Reification ===<br />
<br />
The final major Template Haskell feature not yet described is program ''reification''. Briefly, reification allows a meta program to query compile-time information about other program parts while constructing the object program. It allows the meta program to inspect other program pieces to answer questions such as: "what's this variable's type?", "what are the class instances of this type class?", or "which constructors does this data type have and and how do they look like?". The main use case is to generate boilerplate code which ''auto-completes'' manually written code. A prime example is to generically derive type class instances from bare data type definitions.<br />
<br />
Suppose we've defined the following polymorphic data types for representing potentially erroneous values, lists, and binary trees, respectively:<br />
<br />
<haskell><br />
data Result e a = Err e | Ok a<br />
data List a = Nil | Cons a (List a)<br />
data Tree a = Leaf a | Node (Tree a) a (Tree a)<br />
</haskell><br />
<br />
Moreover, suppose we want to derive <code>Functor</code> instances for all of these types. Deriving these instances manually is straightforward, but writing them all out by hand is quite cumbersome. Especially since writing a <code>Functor</code> instance follows the same pattern across all of the above types and in fact any type <code>T a</code>.<br />
<br />
To make a type constructor <code>T</code> an instance of <code>Functor</code>, one needs to implement method <hask>fmap :: (a -> b) -> T a -> T b</hask>. Its definition is hereby precisely determined by parametricity and the functor laws: By parametricity, all values of type <code>a</code> must be replaced according to the provided function with values of type <code>b</code>. Furthermore, by the functor laws, all other shapes of the input value of type <code>T a</code> must be preserved when transforming it to the output value of type <code>T b</code>.<br />
<br />
Meta function <hask>deriveFunctor :: Name -> Q [Dec]</hask> below implements the idea of this algorithm:<br />
<br />
<haskell><br />
data Deriving = Deriving { tyCon :: Name, tyVar :: Name }<br />
<br />
deriveFunctor :: Name -> Q [Dec]<br />
deriveFunctor ty<br />
= do (TyConI tyCon) <- reify ty<br />
(tyConName, tyVars, cs) <- case tyCon of<br />
DataD _ nm tyVars cs _ -> return (nm, tyVars, cs)<br />
NewtypeD _ nm tyVars c _ -> return (nm, tyVars, [c])<br />
_ -> fail "deriveFunctor: tyCon may not be a type synonym."<br />
<br />
let (KindedTV tyVar StarT) = last tyVars<br />
instanceType = conT ''Functor `appT`<br />
(foldl apply (conT tyConName) (init tyVars))<br />
<br />
putQ $ Deriving tyConName tyVar<br />
sequence [instanceD (return []) instanceType [genFmap cs]]<br />
where<br />
apply t (PlainTV name) = appT t (varT name)<br />
apply t (KindedTV name _) = appT t (varT name)<br />
</haskell><br />
<br />
Given the name of a type constructor (e.g. <code>Result</code>, <code>List</code>, etc.), <hask>deriveFunctor</hask> derives the code for this type constructor's <code>Functor</code> instance. For example, running the splice <hask>$(deriveFunctor ''Tree)</hask> generates the following code:<br />
<br />
<haskell><br />
instance Functor Tree where<br />
fmap f (Leaf x) = Leaf (f x)<br />
fmap f (Node l x r) = Node (fmap f l) (f x) (fmap f r)<br />
</haskell><br />
<br />
Meta function <hask>deriveFunctor</hask> shows reification in action. It calls function <hask>reify :: Name -> Q Info</hask> on the input type constructor's name to yield information about this data type's definition. Using <hask>reify</hask>, it thus learns whether the data type was defined using the <code>data</code> or <code>newtype</code> keyword, which constructors it defines and what their shapes are. Based on the learned structure, <hask>deriveFunctor</hask> is then able to generate a suitable definition of <hask>fmap</hask> and its different clauses via the auxiliaries <hask>genFmap</hask>, <hask>genFmapClause</hask>, and <hask>newField</hask>, defined below. These auxiliary definitions generate one <hask>fmap</hask> clause for each of the data type's constructors. And each clause then transforms its constructor by recursively modifying all of the constructor's fields of type <code>a</code> through <hask>fmap</hask>'s function <code>f</code>, while retaining all other shapes.<br />
<br />
<haskell><br />
genFmap :: [Con] -> Q Dec<br />
genFmap cs<br />
= do funD 'fmap (map genFmapClause cs)<br />
<br />
genFmapClause :: Con -> Q Clause<br />
genFmapClause c@(NormalC name fieldTypes)<br />
= do f <- newName "f"<br />
fieldNames <- replicateM (length fieldTypes) (newName "x")<br />
<br />
let pats = varP f:[conP name (map varP fieldNames)]<br />
body = normalB $ appsE $<br />
conE name : map (newField f) (zip fieldNames fieldTypes)<br />
<br />
clause pats body []<br />
<br />
newField :: Name -> (Name, StrictType) -> Q Exp<br />
newField f (x, (_, fieldType))<br />
= do Just (Deriving typeCon typeVar) <- getQ<br />
case fieldType of<br />
VarT typeVar' | typeVar' == typeVar -><br />
[| $(varE f) $(varE x) |]<br />
ty `AppT` VarT typeVar' |<br />
leftmost ty == (ConT typeCon) && typeVar' == typeVar -><br />
[| fmap $(varE f) $(varE x) |]<br />
_ -> [| $(varE x) |]<br />
<br />
leftmost :: Type -> Type<br />
leftmost (AppT ty1 _) = leftmost ty1<br />
leftmost ty = ty<br />
</haskell><br />
<br />
In more detail, <hask>deriveFunctor</hask> works as follows. First, via <hask>reify</hask> it observes the input data type's name <hask>tyConName</hask>, its declared type variables <hask>tyVars</hask>, and its exposed constructors <hask>cs</hask>. It then determines the data type's right-most type variable <hask>tyVar</hask> and stores it together with the data type's type constructor name <hask>tyConName</hask> in the <hask>Q</hask> monad's user state. This state information is retrieved later again from inside auxiliary definition <hask>newField</hask>. Next, <hask>deriveFunctor</hask> derives a <hask>Functor</hask>'s <hask>fmap</hask> definition using auxiliary <hask>genFmap</hask>. For each of the input data type's value constructors <hask>cs</hask>, <hask>genFmap</hask> generates an <hask>fmap</hask> clause using helper function <hask>genFmapClause</hask>. The latter recursively maps the provided function <hask>f :: a -> b</hask> over all of a constructor's fields of type <code>a</code>, while leaving all other fields untouched. Each field is hereby modified through <hask>f</hask> or left unchanged by auxiliary <hask>newField</hask> based on the field's type: if a field's type is <code>a</code> (which is stored in the retrieved <hask>tyVar</hask> inside function <hask>newField</hask>), then <hask>f</hask> needs to be applied to it; otherwise it needs to remain unchanged.<br />
<br />
<br />
In an analogous manner to <hask>deriveFunctor</hask>, a function <hask>deriveFoldable :: Name -> Q [Dec]</hask> can be devised to derive a data type's <code>Foldable</code> instance. All that is needed is to provide a definition for function <hask>foldMap :: Monoid m => (a -> m) -> T a -> m</hask>. Again, <hask>foldMap</hask>'s definition follows directly from a data type's bare definition, which can be observed by means of reification. This highlights particularly how the functionality offered by Template Haskell provides a low-level API into the GHC compiler to manipulate abstract syntax trees at compile-time. This mechanism is quite powerful and even allows to simulate some of GHC's offered language extensions, e.g., <code>-XDeriveFunctor</code> and <code>-XDeriveFoldable</code>, to be implemented as a library on top of Template Haskell.<br />
<br />
== Template Haskell for building Embedded Domain specific Languages (EDSLs) ==<br />
<br />
To see Template Haskell's potential for building an EDSL, consider the problem of pattern matching text with regular expressions. Suppose, as part of a Haskell program we need to devise many different regular expressions and use them to pattern match text fragments. Regular expressions are easily defined by an algebraic data type capturing their structure, as well as an evaluator checking whether a regular expression matches some input string. <ref>This example draws on Penn's CIS 552 ''Advanced Programming'' course, specifically Assignment 5: http://www.seas.upenn.edu/~cis552/current/hw/hw05/Main.html.</ref><br />
<br />
<haskell><br />
data RegExp<br />
= Char (Set Char) -- [a], [abc], [a-z]; matches a single character from the specified class<br />
| Alt RegExp RegExp -- r1 | r2 (alternation); matches either r1 or r2<br />
| Seq RegExp RegExp -- r1 r2 (concatenation); matches r1 followed by r2<br />
| Star RegExp -- r* (Kleene star); matches r zero or more times<br />
| Empty -- matches only the empty string<br />
| Void -- matches nothing (always fails)<br />
| Var String -- a variable holding another regexp (explained later)<br />
deriving Show<br />
<br />
match :: RegExp -> String -> Bool<br />
match r s = nullable (foldl deriv r s)<br />
</haskell><br />
<br />
The evaluator <hask>match</hask> is hereby based on the concept of derivatives<ref name="regexp-derivs" />: an initial regular expression <hask>r</hask> matches an input string <hask>s</hask>, if <hask>r</hask> matches the first character of <hask>s</hask> and its derivative regular expression <hask>(deriv r)</hask> matches the remainder of <hask>s</hask>:<br />
<br />
<haskell><br />
nullable :: RegExp -> Bool<br />
nullable (Char _) = False<br />
nullable (Alt r1 r2) = nullable r1 || nullable r2<br />
nullable (Seq r1 r2) = nullable r1 && nullable r2<br />
nullable (Star _) = True<br />
nullable Empty = True<br />
nullable Void = False<br />
nullable (Var _) = False<br />
<br />
deriv :: RegExp -> Char -> RegExp<br />
deriv (Char cs) c<br />
| c `Set.member` cs = Empty<br />
| otherwise = Void<br />
deriv (Alt r1 r2) c = Alt (deriv r1 c) (deriv r2 c)<br />
deriv (Seq r1 r2) c<br />
| nullable r1 = Alt (Seq (deriv r1 c) r2) (deriv r2 c)<br />
| otherwise = Seq (deriv r1 c) r2<br />
deriv (Star r) c = deriv (Alt Empty (Seq r (Star r))) c<br />
deriv Empty _ = Void<br />
deriv Void _ = Void<br />
deriv (Var _) _ = Void<br />
</haskell><br />
<br />
The <code>RegExp</code> data type and the <hask>match</hask> function solve the initially posed problem of providing regular expressions in Haskell. However, specifying regular expressions in abstract syntax is extremely tedious. For example, consider defining a regular expression for checking the wellformedness of email addresses ending with the top level domain '''.com'''. In its usual concrete syntax, such a regular expression is easily defined as <code>([a-z]|[0-9])*@([a-z]|[0-9])*.com</code>, but writing it in terms of the <code>RegExp</code> dataype is verbose and unintuitive. Moreover, parsing functions like<br />
<br />
* <hask>compile :: String -> RegExp</hask>, or<br />
* <hask>compile' :: String -> Either CompileError RegExp</hask><br />
<br />
do not remedy the problem of working with regular expressions in concrete syntax. Due to "compiling" regular expressions at run time, they don't provide any compile-time type-safety guarantees that the input raw expression is wellformed; thus they lead to either run time exceptions for illformed regular expressions (e.g., <hask>compile</hask>) or induce a tedious handling for compiled regexes (e.g., <hask>compile'</hask>).<br />
<br />
To preserve type safety and yet to be able to use regular expressions conveniently, we want to embed the concrete regular expression syntax into the Haskell host language. This can be done via Template Haskell's quasi quotes and furthermore enabling the <code>QuasiQuotes</code> extension. This allows defining ''quasi quotes'' for regular expressions, denoted <code>[regex| .. |]</code>, where anything inside the quasi quote is considered part of an embedded regular expression language. Using quasi quotes, we can then specify the regex for email addresses from above naturally as follows:<br />
<br />
<haskell><br />
validDotComMail :: RegExp<br />
validDotComMail = [regex|([a-z]|[0-9])*@([a-z]|[0-9])*.com|]<br />
</haskell><br />
<br />
We can even compose regular expressions easily from smaller building blocks:<br />
<br />
<haskell><br />
alphaNum, validDotComMail' :: RegExp<br />
alphaNum = [regex|[a-z]|[0-9]|]<br />
validDotComMail' = [regex|${alphaNum}*@${alphaNum}*.com|]<br />
</haskell><br />
<br />
Writing <hask>${alphaNum}</hask> interpolates the regex referred to by <hask>alphaNum</hask> into the larger regex <hask>validDotComMail'</hask>. In essence, this means that we can define our own notion of splicing values from the Haskell meta language into the embedded object language of regular expressions. We can go further and even allow to run Haskell code when interpolating with <code>${..}</code>. For example, refining our wellformedness check for '''.com''' mail addresses, we might want to ensure at least one character to occur on either side of the "@" symbol:<br />
<br />
<haskell><br />
chars, validDotComMail'' :: RegExp<br />
chars = [regex|[a-z]|[A-Z]|[0-9]|[-_.]|]<br />
validDotComMail'' = [regex|${plus chars}@${plus chars}.com|]<br />
<br />
plus :: RegExp -> RegExp<br />
plus r = Seq r (Star r)<br />
</haskell><br />
<br />
Here, <hask>plus</hask> corresponds to the usual regex combinator that requires a given regex to occur at least once. Note how <hask>plus</hask> is defined as a regular Haskell function and then used ''inside'' of the embedded regex language to build the regular expression for <hask>validDotComMail''</hask>.<br />
<br />
Intuitively, a quasi quote like <code>[regex| .. |]</code> converts an embedded language's concrete syntax to Haskell code at compile-time. It is defined by a ''quasi quoter'', which is a parser for the embedded language. Its task is to parse the embedded language's syntax into a corresponding Template Haskell expression and then to splice this expression as real Haskell code in place of the quasi quote. The conversion of embedded language code to corresponding Haskell code hereby happens before typechecking the Haskell module. Hence, trying to splice in malformed embedded language fragments will raise a Haskell type error at compile-time.<br />
<br />
The quasi quoter <code>regex</code> for our embedded language of regular expressions can be defined as follows:<br />
<br />
<haskell><br />
regex :: QuasiQuoter<br />
regex = QuasiQuoter {<br />
quoteExp = compile<br />
, quotePat = notHandled "patterns"<br />
, quoteType = notHandled "types"<br />
, quoteDec = notHandled "declarations"<br />
}<br />
where notHandled things = error $<br />
things ++ " are not handled by the regex quasiquoter."<br />
<br />
compile :: String -> Q Exp<br />
compile s =<br />
case P.parse regexParser "" s of<br />
Left err -> fail (show err)<br />
Right regexp -> [e| regexp |]<br />
</haskell><br />
<br />
That is, formally a <code>QuasiQuoter</code> consists of four parsers,<br />
<br />
<haskell><br />
quoteExp :: String -> Q Exp<br />
quotePat :: String -> Q Pat<br />
quoteType :: String -> Q Type<br />
quoteDec :: String -> Q Dec<br />
</haskell><br />
<br />
to parse raw strings of the embedded language into the different categories of Haskell syntax. In this example, however, we only want to splice embedded regular expressions into the context of Haskell expressions, so we only define the <code>quoteExp</code> parser in the <code>regex</code> quasi quoter. This parser compiles an embedded regular expression given as a string into a corresponding Template Haskell expression.<br />
<br />
Compilation by the <hask>compile</hask> function proceeds in two stages: First, we parse the input string regex into a corresponding <code>RegExp</code> value. Second, we encode this <code>RegExp</code> value as a Haskell expression in Template Haskell's <code>Q Exp</code> type. It is the second step that allows us to interpolate variables (or even code) from the Haskell host language into the EDSL for regular expressions.<br />
<br />
Parsing a raw regular expression into a corresponding <code>RegExp</code> value is a routine task using (e.g.) the ''parsec'' library:<br />
<br />
<haskell><br />
regexParser :: Parsec String () RegExp<br />
regexParser = alts <* eof where<br />
atom = try var <|> char<br />
var = Var <$> (string "${" *> many1 (noneOf "}") <* P.char '}')<br />
char = charclass <|> singlechar<br />
singlechar = (Char . Set.singleton) <$> noneOf specials<br />
charclass = fmap (Char . Set.fromList) $<br />
P.char '[' *> content <* P.char ']'<br />
content = try (concat <$> many1 range)<br />
<|> many1 (noneOf specials)<br />
range = enumFromTo<br />
<$> (noneOf specials <* P.char '-')<br />
<*> noneOf specials<br />
alts = try (Alt <$> seqs <*> (P.char '|' *> alts)) <|> seqs<br />
seqs = try (Seq <$> star <*> seqs) <|> star<br />
star = try (Star <$> (atom <* P.char '*'))<br />
<|> try (Star <$> (P.char '(' *> alts <* string ")*"))<br />
<|> atom<br />
specials = "[]()*|"<br />
</haskell><br />
<br />
To represent regular expressions of type <code>RegExp</code> as Template Haskell expressions of type <code>Q Exp</code>, Template Haskell's <code>Lift</code> typeclass is used. Its method <hask>lift :: Lift a => a -> Q Exp</hask> lifts values from the Haskell meta language (e.g., a <code>RegExp</code> value) into Template Haskell's expression language (i.e., a <code>Q Exp</code> value). The <hask>lift</hask> function is implicitly invoked by quote <hask>[e| regexp |]</hask> in function <code>compile</code>.<br />
<br />
<br />
Most of the lifting is a direct encoding of the syntactic structure of the <code>RegExp</code> value; the only interesting case is when lifting the regular expression variable <hask>Var vars</hask>. In this case, we treat the words in the string <hask>vars</hask> as referring to identifiers from the Haskell host language, which we apply in a left associative manner to each other. Doing this enables interpolation of Haskell identifiers or even simple forms of Haskell expressions into our EDSL of regular expressions as shown by the regexes <hask>validDotComMail'</hask>, and <hask>validDotComMail''</hask> above.<br />
<br />
<haskell><br />
instance Lift a => Lift (Set a) where<br />
lift set = appE (varE `Set.fromList) (lift (Set.toList set))<br />
<br />
instance Lift RegExp where<br />
-- lift :: RegExp -> Q Exp<br />
lift (Char cs) = apply `Char [lift cs]<br />
lift (Alt r1 r2) = apply `Alt (map lift [r1, r2])<br />
lift (Seq r1 r2) = apply `Seq (map lift [r1, r2])<br />
lift (Star r1) = apply `Star (map lift [r1])<br />
lift Empty = apply `Empty []<br />
lift Void = apply `Void []<br />
lift (Var vars) = foldl1 appE $ map (varE . mkName) (words vars)<br />
<br />
apply :: Name -> [Q Exp] -> Q Exp<br />
apply n = foldl appE (conE n)<br />
</haskell><br />
<br />
These two steps constitute the conversion of raw string regular expressions into Template Haskell expressions inside of the <hask>compile</hask> function and define the <code>regex</code> quasiquoter. Whenever we write a quasi quote like <hask>[regex| .. |]</hask> in a Haskell expression context, <hask>regex</hask>'s parser <hask>quoteExp</hask> converts the regex EDSL into a Template Haskell expression <code>Q Exp</code> and splices in the result as a wellformed <code>RegExp</code> value. This example shows how Template Haskell and quasi quotes can be used to define a type-safe, domain specific language for regular expressions.<br />
<br />
=== Shakespearean Templates ===<br />
<br />
In much the same manner as in the last example, Template Haskell and quasi quotes are used in Michael Snoyman's <code>shakespeare</code> library<ref name="shakespeare" /><ref name="shakespeare-lib" />. It defines embedded templating languages for working with the internet's web languages from within a Haskell web application. In particular, the <code>shakespeare</code> library provides the template languages ''Hamlet'', ''Cassius'', and ''Julius'' for writing embedded HTML, CSS, and Javascript code, respectively. All three templating languages internally work quite similarly to the previous example's EDSL for regular expressions: quasi quotes allow one to write HTML, CSS, or JavaScript code in concrete (though slightly modified) syntax inside of Haskell. Moreover, identifiers from the Haskell host language as well as code fragments can be interpolated into the template languages at compile-time. In the remainder we will briefly show-case the <code>shakespeare</code> library's templating language Hamlet for creating HTML documents; the other templating languages Cassius and Julius are similar.<br />
<br />
To create and output a simple web page from inside a Haskell application, the following is enough:<br />
<br />
<haskell><br />
import Data.Text<br />
import Text.Hamlet<br />
import Text.Blaze.Html.Renderer.String<br />
<br />
data Page = Home | About | Github<br />
<br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls Github _ = "https://www.github.com/bollmann"<br />
<br />
webPage :: Text -> Text -> HtmlUrl Page<br />
webPage title content = [hamlet|<br />
<html><br />
<head><br />
<title>#{Text.toUpper title}<br />
<body><br />
<h1>#{title}<br />
<div>Welcome to my Shakespearean Templates page!<br />
<hr><br />
<div>Links:<br />
<ul><br />
<a href=@{Home}>My Homepage<br />
<a href=@{About}>About me<br />
<a href=@{Github}>Check out my Github<br />
<hr><br />
<div>#{content}<br />
|]<br />
<br />
main = putStrLn $ renderHtml $<br />
webPage "Hello Shakespeare!" "Hello World!" mkUrls<br />
</haskell><br />
<br />
Running this Haskell program, outputs an HTML page as specified by the Hamlet templating language, embedded through quasi quote <hask>[hamlet| .. |]</hask> in function <hask>webPage</hask>. Hamlet closely resembles real HTML syntax, but is even more terse: instead of a closing HTML tag, Hamlet uses indentation to indicate the span of the tag. Furthermore, Hamlet allows to interpolate code or identifiers from the Haskell host language when creating an HTML template. Interpolation of Haskell code into Hamlet is done by writing <code>#{ .. }</code>. In the above example, the HTML page's title and content are interpolated from Haskell identifiers. Note particularly how in the webpage's title we uppercase the interpolated title using Haskell's <hask>Text.toUpper</hask> function ''inside'' of the Hamlet language.<br />
<br />
In addition to this standard interpolation, Hamlet can also interpolate links by writing <code>@{..}</code>. These links are specified as values of the <hask>Page</hask> data type inside the template and the <hask>mkUrls</hask> render function translates them to real URLs later. Hamlet's URL interpolation has commonly be phrased as creating "type-safe URLs". One reason is that, just like with normal variable interpolation, all interpolated links have to exist and be type correct at compile-time; in this case, links must be values of the <code>Page</code> data type. Hence, as soon as a link's constructor shape is changed, the compiler statically forces us to update all references to this link as well. Furthermore, there is only one distinct place in the code to maintain or update a link's raw URL, thus minimizing the risk of dead URLs.<br />
<br />
For example, suppose we want to add more external links to our web page. We could model this fact by changing the <hask>Page</hask> data type to<br />
<br />
<haskell><br />
data Page = Home | About | External ExternalPage<br />
data ExternalPage = Github | Haskell | Reddit<br />
</haskell><br />
<br />
and, moreover, changing the <hask>mkUrls</hask> renderer function to account for the new links:<br />
<br />
<haskell><br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls (External page) _ = mkExternalUrls page<br />
<br />
mkExternalUrls :: ExternalPage -> Text<br />
mkExternalUrls Github = "https://www.github.com"<br />
mkExternalUrls Haskell = "http://www.haskell.org"<br />
mkExternalUrls Reddit = "http://www.reddit.com/r/haskell"<br />
</haskell><br />
<br />
Doing just these changes, will then cause a compile-time error in our <hask>webPage</hask> template, since we haven't updated the <hask>Github</hask> reference to our newly adjusted link structure. Hence, the compiler reminds (and in fact forces) us to update all locations in the code that used the old <hask>Github</hask> link to now use the new <hask>External Github</hask> (as well as optionally the <hask>External Haskell</hask>, etc.) links.<br />
<br />
Finally, Hamlet allows to use some control constructs like if conditionals, for loops, and let bindings to embed basic business logic into a webpage's template. Michael Snoyman gives a gentle (and much more in-depth) introduction to shakespearean templates and Yesod<ref name="shakespeare" /><ref name="yesod" />.<br />
<br />
= References =<br />
<br />
<references><br />
<ref name="th1">Tim Sheard and Simon Peyton Jones. Template Meta-Programming for Haskell. SIGPLAN Not., 37(12):60-75, December 2002. URL: https://www.microsoft.com/en-us/research/publication/template-meta-programming-for-haskell/?from=http://research.microsoft.com/~simonpj/papers/meta-haskell/ </ref><br />
<ref name="th2">Tim Sheard and Simon Peyton Jones. Notes on Template Haskell, Version 2. URL: https://www.haskell.org/ghc/docs/papers/th2.ps, 2003.</ref><br />
<ref name="th3">Simon Peyton Jones. Major Proposed Revision of Template Haskell. URL: https://ghc.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposal, 2010</ref><br />
<ref name="qq">Geoffrey Mainland. Why it's nice to be quoted: Quasiquoting for Haskell. In ''Proceedings of the ACM SIGPLAN Workshop on Haskell'', Haskell '07, pages 73-82, New York, NY, USA, 2007. ACM</ref><br />
<ref name="regexp-derivs">Janusz A. Brzozowski. Derivatives of regular expressions. J. ACM, 11(4):481–494, October 1964.</ref><br />
<ref name="shakespeare">Michael Snoyman. Shakespearean Templates. URL: http://www.yesodweb.com/book/shakespearean-templates [Accessed: May 2016].</ref><br />
<ref name="shakespeare-lib">Michael Snoyman. The <code>shakespeare</code> Haskell library. URL: http://hackage.haskell.org/package/shakespeare [Accessed: May 2016].</ref><br />
<ref name="yesod">Michael Snoyman. Haskell and Yesod. URL: http://www.yesodweb.com/book-1.4 [Accessed: May 2016].</ref><br />
<ref name="dep-tys">Daniel Friedlender and Mia Indrika. Do we need Dependent Types? J. Funct. Program. 10(4):409-415, July 2000.</ref><br />
</references></div>Enoksrdhttps://wiki.haskell.org/index.php?title=A_practical_Template_Haskell_Tutorial&diff=62532A practical Template Haskell Tutorial2018-06-21T20:12:04Z<p>Enoksrd: /* Reification */ Fix syntax</p>
<hr />
<div>This tutorial explores the Glasgow Haskell Compiler's compile-time meta programming in Template Haskell. It motivates use cases for meta programming and explains the different Template Haskell features on simple toy programs. The aim is to give an overview of Template Haskell's functionality in an example-driven manner.<br />
<br />
= Introduction =<br />
<br />
Template Haskell (TH) is the standard framework for doing type-safe, compile-time meta programming in the Glasgow Haskell Compiler (GHC). It allows writing Haskell meta programs, which are evaluated at compile-time, and which produce Haskell programs as the results of their execution.<br />
<br />
Template Haskell was conceived by Tim Sheard and Simon Peyton Jones<ref name="th1" /> by drawing on the ideas of Lisp macros, but in the typed setting of Haskell. Since then, the original implementation has evolved quite a bit<ref name="th2" /><ref name="th3" />. Most notably, in 2007 Geoffrey Mainland added support for quasi quoting<ref name="qq" />, which makes the embedding of domain specific languages into the Haskell host language much easier.<br />
<br />
As it exists today, Template Haskell has two main areas of application: Haskell code generation at compile-time and facilitating the embedding of domain specific languages.<br />
<br />
As a code generator, Template Haskell empowers a user to write many, syntactically different, programs all at once by means of a single meta program. All that is needed is a uniform, algorithmic description to create the different result programs. And the meta program then precisely implements the algorithm to compute all the different result programs as its output. This proves useful for example to avoid writing the same repetitive, boilerplate code over and over again. To this end, Template Haskell is used (among many others) in the <code>aeson</code> library to automatically derive a data type's <code>ToJSON</code> and <code>FromJSON</code> instances for JSON serialization; and in the <code>lens</code> library to mechanically create a data type's lenses.<br />
<br />
As a framework for creating domain specific languages (EDSLs), Template Haskell allows a user to embed programs written in another programming language inside of a Haskell program. This enables writing parts of the program in the concrete, domain specific syntax of a different programming language. It has the benefit to think about -- and to express -- domain specific problems in the language best suited for the task. In particular, it lets a user focus on the domain specific problem and removes all additional language burdens induced by inconvenient syntax, unsuited control constructs, etc. Programs from the embedded language are parsed and translated into corresponding (but syntactically heavier) Haskell code at compile-time by Template Haskell. In this sense, (e.g.,) the shakespearean template languages from the <code>shakespeare</code> library use Template Haskell at their core. They expose succinct domain specific languages to write HTML, CSS, and Javascript code inside of a Haskell based web application.<br />
<br />
= Template Haskell by Examples =<br />
<br />
In this section, we will review the Template Haskell features to write meta programs. The first set of examples show-cases Template Haskell's potential as a code generator; the second set of examples highlights its facilities to create embedded domain specific languages (EDSLs). All examples require GHC's language extension <code>TemplateHaskell</code> to be enabled.<br />
<br />
To avoid confusion in the sequel, we distinguish between meta programs and object programs. Meta programs are the Haskell programs that run at compile-time and which generate Template Haskell object programs as the results of their execution; they are the programs that devise or manipulate other programs by some algorithmic means. Object programs, on the other hand, are the Template Haskell programs manipulated and built by the Haskell meta programs at compile-time.<br />
<br />
== Template Haskell as a Code Generator ==<br />
<br />
As an introductory example, consider Haskell's <code>Prelude</code> function <hask>curry :: ((a,b) -> c) -> a -> b -> c</hask>, which converts a function taking a pair to its curried equivalent. Unfortunately, there are no <code>Prelude</code> functions that provide the same currying functionality for functions taking arbitrary <math>n</math>-tuples. Moreover, having to write more than a few of these functions manually is, while trivial, a very repetitive and cumbersome task. Instead we wish to generate needed <hask>curry3</hask>, <hask>curry5</hask>, or <hask>curry8</hask> functions through a single meta program on demand. Template Haskell lets us do just this. The idea is to write a meta function <hask>curryN :: Int -> Q Exp</hask> which, given a number <code>n >= 1</code>, constructs the ''source code'' for an <math>n</math>-ary <hask>curry</hask> function:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import Control.Monad<br />
import Language.Haskell.TH<br />
<br />
curryN :: Int -> Q Exp<br />
curryN n = do<br />
f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
let args = map VarP (f:xs)<br />
ntup = TupE (map VarE xs)<br />
return $ LamE args (AppE (VarE f) ntup)<br />
</haskell><br />
<br />
For input <math>n</math>, meta function <hask>curryN</hask> builds a lambda abstraction <hask>LamE</hask> that pattern matches against a function <hask>f</hask> and <math>n</math> argument variables <hask>x1</hask>, <hask>x2</hask>, ..., <hask>xn</hask>; in its body, it then applies function <hask>f</hask> to the <math>n</math>-tuple <hask>(x1, x2, ..., xn)</hask> derived from the pattern matched variables. The names used to refer to the variables <hask>f</hask> and <hask>x1</hask> through <hask>xn</hask> are generated monadically by function <hask>newName :: String -> Q Name</hask> to always generate fresh names not used anywhere else. Hence, the value returned by <hask>curryN</hask> is a monadic computation of type <code>Q Exp</code>. When executed, this monadic computation yields an expression <code>Exp</code> representing the object program of an <math>n</math>-ary curry function. For example, <hask>(curryN 3)</hask> returns a monadic computation that yields an expression representing a <hask>curry3</hask> function of type <hask>((a, b, c) -> d) -> a -> b -> c -> d</hask> in abstract syntax.<ref>Note that meta function <hask>curryN</hask> cannot be written in normal Haskell per se as the type for a generated <math>n</math>-ary curry function depends on <math>n</math>. Thus, the definition of <hask>curryN</hask> requires ''dependent types'' to be expressed in Haskell, a feature not yet present. However, there already exist ingenious alternatives to "faking" dependent types in Haskell; see for instance [http://www.brics.dk/RS/01/10/ this paper] for a solution to simulate functions like <hask>curryN</hask> without dependent types).</ref><br />
<br />
<br />
To run a meta program like <hask>curryN</hask> at compile-time, we enclose it with Template Haskell's ''splice'' operator <code>$</code> by writing (e.g.,) <hask>$(curryN 3)</hask>. This evaluates the meta program <code>curryN 3</code> and puts the resulting object program <hask>\f x1 x2 x3 -> f (x1, x2, x3)</hask> in place of the splice. In general, the splice operator <code>$</code> can be applied to any monadic <code>Q</code> computation, hereby performing this computation at compile-time and inserting the resulting object program as real Haskell code. To ensure type safety, meta programs to be run are type checked beforehand to indeed yield a valid Template Haskell object program. Hence, only imported, fully-typechecked meta programs can be run via the splice operator <code>$</code>: in particular, we have to evaluate the meta program <code>$(curryN 3)</code> in a separate module to where <code>curryN</code> is defined.<br />
<br />
To generate function declarations for the first <math>n</math> curry functions, we can devise a further meta program on top of <hask>curryN</hask> as follows:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
Running <hask>$(genCurries 20)</hask> will then splice in the first 20 curry functions at compile-time, namely:<br />
<br />
<haskell><br />
curry1 = \ f x1 -> f (x1)<br />
curry2 = \ f x1 x2 -> f (x1, x2)<br />
curry3 = \ f x1 x2 x3 -> f (x1, x2, x3)<br />
curry4 = \ f x1 x2 x3 x4 -> f (x1, x2, x3, x4)<br />
...<br />
curry20 = \ f x1 x2 ... x20 -> f (x1, x2, ..., x20)<br />
</haskell><br />
<br />
Note that in this case, <hask>genCurries</hask> returns a list of top-level function declarations that bind the anonymous lambda abstractions built by <hask>curryN</hask>. Also, to name the function bindings, we use function <hask>mkName :: String -> Name</hask> instead of <hask>newName :: String -> Q Name</hask>. The reason is that here we want to generate functions <hask>curry1</hask> to <hask>curry20</hask> with exactly the prescribed names, so they can be captured and referred to from other parts of the program.<br />
<br />
Evaluating Haskell (meta) programs at compile-time and splicing in the generated object programs as regular Haskell code is the first central building block of Template Haskell. The two other core mechanisms are exhibited by the implementations of <hask>curryN</hask> and <hask>genCurries</hask>: algebraic data types and the quotation monad <code>Q</code>.<br />
<br />
First, object programs created by Template Haskell are represented as regular algebraic data types, describing a program in the form of an abstract syntax tree. The Template Haskell library provides algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> to represent Haskell's surface syntax of expressions, patterns, declarations, and types, respectively. Virtually every concrete Haskell syntactic construct has a corresponding abstract syntax constructor in one of the four ADTs. Furthermore, all Haskell identifiers are represented by the abstract <code>Name</code> data type. By representing object programs as regular algebraic data types (and thus as data), normal Haskell can be used as the meta programming language to build object programs.<br />
<br />
Second, TH object programs are built inside the quotation monad <code>Q</code>. This monad is performed by the splice operator "<code>$</code>" at compile-time as part of evaluating the meta program. In the examples so far, the <code>Q</code> monad was only needed to provide fresh identifiers with function <hask>newName :: String -> Q Name</hask> for the generated Haskell expressions. The other main feature that requires a monadic construction of object programs is ''reification'', which allows to query compile-time information during the object program's construction. We will explain reification in detail later.<br />
<br />
Thus, Template Haskell's core functionality constitutes evaluating object programs with "<code>$</code>" and building them from algebraic data types inside the quotation monad <code>Q</code>. However, constructing object programs in terms of their abstract syntax trees is quite verbose and leads to clumsy meta programs. Therefore the Template Haskell API also provides two further interfaces to build object programs more conveniently: ''syntax construction functions'' and ''quotation brackets''.<br />
<br />
Syntax construction functions directly relate to the syntax constructors from the algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> for representing Haskell code. However, they hide the monadic nature of building object programs. For example, recall our definition of the <hask>genCurries</hask> meta function from above:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
To use the object program generated by the sub call to <hask>curryN</hask> in the larger context of the returned function declaration, we have to first perform <hask>curryN</hask> and bind its result to <hask>cury</hask>. The reason is that we have to account for <hask>curryN</hask>'s generation of fresh names before we can continue. Using syntax construction functions instead of data constructors, however, abstracts from the monadic construction of <hask>genCurries</hask>, thus making its code a little shorter:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = funD name [clause [] (normalB (curryN ith)) []]<br />
where name = mkName $ "curry" ++ show ith<br />
</haskell><br />
<br />
The new <code>funD</code>, <code>clause</code>, and <code>normalB</code> functions directly correspond to the formerly used <code>FunD</code>, <code>Clause</code>, and <code>NormalB</code> constructors. The only difference lies in their types:<br />
<br />
{|<br />
|-<br />
|<hask>FunD :: Name -> [Clause] -> Dec</hask><br />
|<hask>funD :: Name -> [Q Clause] -> Q Dec</hask><br />
|-<br />
|<hask>Clause :: [Pat] -> Body -> Clause</hask><br />
|<hask>clause :: [Q Pat] -> Q Body -> Q Clause</hask><br />
|-<br />
|<hask>NormalB :: Exp -> Body</hask><br />
|<hask>normalB :: Q Exp -> Q Body</hask><br />
|}<br />
<br />
While the syntax constructors work with raw TH expressions, the syntax construction functions expect their monadic counterparts. They construct a TH object program directly in <code>Q</code>, thus freeing the API consumer from doing the monadic wrapping and unwrapping manually. For every syntax constructor, there is a corresponding monadic syntax construction function provided.<br />
<br />
On top of syntax construction functions, quotation brackets are a further shortcut for representing Haskell code. They allow to specify an object program using just regular Haskell syntax by enclosing it inside oxford brackets <code>[| .. |]</code>. That way, object programs can be specified yet much more succinctly. For example, a meta program building a Haskell expression for the identity function is still quite verbose, if expressed with either ADTs or syntax construction functions:<br />
<br />
<haskell><br />
genId :: Q Exp<br />
genId = do<br />
x <- newName "x"<br />
lamE [varP x] (varE x)<br />
</haskell><br />
<br />
Using quotation brackets, writing the same meta program can be abbreviated much further as:<br />
<br />
<haskell><br />
genId' :: Q Exp<br />
genId' = [| \x -> x |]<br />
</haskell><br />
<br />
Quotation brackets quote regular Haskell code as the corresponding object program fragments inside the <code>Q</code> monad. There are quotation brackets for quoting Haskell expressions (<code>[e| .. |]|</code>), patterns (<code>[p| .. |]</code>), declarations (<code>[d| .. |]</code>), and types (<code>[t| .. |]</code>). Writing <code>[| .. |]</code> is hereby just another way of saying <code>[e| .. |]</code>. Using quotation brackets in a sense ''lifts'' Haskell's concrete syntax into corresponding object program expressions inside the <code>Q</code> monad. By doing so, quotation brackets represent the dual of the already introduced splice operator <code>$</code>: Evaluating a meta program with "<code>$</code>" splices in the generated object program as real Haskell code; in contrast, quotation brackets <code>[| .. |]</code> turn real Haskell code into an object program. Consequently, quotation brackets and the splice operator cancel each other out. The equation <code>$([| e |]) = e</code> holds for all expressions <code>e</code> and similar equations hold for declarations, and types<ref name="th2" />.<br />
<br />
In addition, there is support for quoting Haskell (value and type) identifiers as corresponding <code>Name</code>s inside Template Haskell. This allows to refer to regular Haskell identifiers from within TH object programs. For example, writing <hask>'genId</hask> yields a TH <code>Name</code> referring to the <hask>genId</hask> identifier. Similarly, <hask>''Q</hask> gives a <code>Name</code> referring to the <code>Q</code> type identifier.<br />
<br />
=== Generic Maps ===<br />
<br />
As a second example that uses both syntax construction functions as well as quotation brackets, let's consider a meta program <hask>mapN :: Int -> Q Dec</hask> to build "generic" <hask>map</hask> functions at compile-time. Invoking <hask>$(mapN 1)</hask> should generate the well-known standard function <hask>map :: (a -> b) -> [a] -> [b]</hask>; evaluating <hask>$(mapN 2)</hask> should splice in a binary map function of type <hask>(a -> b -> c) -> [a] -> [b] -> [c]</hask>, and so on.<ref>Note that <math>n</math>-ary maps are better written using Applicative Functors and <code>ZipList</code>s, as this allows to define them first-class from within regular Haskell. For understanding Template Haskell as a code generator, this example is still useful though.</ref><br />
<br />
<haskell><br />
mapN :: Int -> Q Dec<br />
mapN n<br />
| n >= 1 = funD name [cl1, cl2]<br />
| otherwise = fail "mapN: argument n may not be <= 0."<br />
where<br />
name = mkName $ "map" ++ show n<br />
cl1 = do f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
ys <- replicateM n (newName "ys")<br />
let argPatts = varP f : consPatts<br />
consPatts = [ [p| $(varP x) : $(varP ys) |]<br />
| (x,ys) <- xs `zip` ys ]<br />
apply = foldl (\ g x -> [| $g $(varE x) |])<br />
first = apply (varE f) xs<br />
rest = apply (varE name) (f:ys)<br />
clause argPatts (normalB [| $first : $rest |]) []<br />
cl2 = clause (replicate (n+1) wildP) (normalB (conE '[])) []<br />
</haskell><br />
<br />
The implementation of <hask>mapN</hask> is very much in the spirit of meta function <hask>curryN</hask> from the first example. For instance, evaluating splice <hask>$(mapN 3)</hask> splices in the following map function at compile-time:<br />
<br />
<haskell><br />
map3 f (x:xs) (y:ys) (z:zs) = f x y z : map3 f xs ys zs<br />
map3 _ _ _ _ = []<br />
</haskell><br />
<br />
Nonetheless, meta function <hask>mapN</hask> exhibits a couple of new Template Haskell features: First, quotation brackets and splices are used in several places to abbreviate the object program construction. For example, helper definition <hask>apply</hask> used to generate <hask>map3</hask>'s body <hask>f x y z : map3 f xs ys zs</hask> shows the use of quotation brackets; it also highlights how splicing (<hask>$</hask>) and quotes (<hask>[| .. |]</hask>) cancel each other out. Second, identifier quotes (namely, <hask>'[]</hask>) are used to create an object program <code>Name</code> that refers to Haskell's built-in list constructor <hask>[]</hask>. Third, the example advertises how all three APIs for building Template Haskell object programs can be interleaved. The lowermost verbose API of building a raw TH data value inside the quotation monad <code>Q</code> can be abbreviated, where possible, with syntax constructor functions and quotation brackets.<br />
<br />
Lastly, the <hask>mapN</hask> example exemplifies how Haskell's static scoping is extended to object programs. The scoping principle for object programs is just as in normal Haskell: Identifiers are bound to their lexically enclosing binders in scope at the point the object program is ''defined''. Quotation brackets and splices don't alter static scopes, even though splices may bring an object program into scope at a location, where a conflicting closure is present. For example, consider this snippet:<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
static :: Q Exp<br />
static = [| x |]<br />
<br />
plus42 :: Int -> Int<br />
plus42 x = $static + x<br />
</haskell><br />
<br />
Here the occurrence of <hask>x</hask> in <hask>static</hask> refers to the global identifier <hask>x</hask> that is lexically in scope during its definition. Splicing in <hask>static</hask> into a different scope later where a different local <hask>x</hask> is present (i.e., <hask>plus42</hask>'s local identifier <hask>x</hask>), doesn't alter the link between <hask>static</hask>'s <hask>x</hask> and the global identifier <hask>x</hask>.<br />
<br />
The only exception to static scoping in Template Haskell are the names generated by <hask>mkName :: String -> Name</hask>. These names implement dynamic scoping and ''can'' be captured in spliced-in code. Changing the previous snippet to<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
dynamic :: Q Exp<br />
dynamic = VarE (mkName "x")<br />
<br />
times2 :: Int -> Int<br />
times2 x = $dynamic + x<br />
</haskell><br />
<br />
results in the identifier <hask>x</hask> spliced in by <hask>$dynamic</hask> to be bound to the closest <hask>x</hask> in scope. Hence, its binder is <hask>times2</hask>'s local identifier <hask>x</hask> and ''not'' the global <hask>x</hask>.<br />
<br />
=== Reification ===<br />
<br />
The final major Template Haskell feature not yet described is program ''reification''. Briefly, reification allows a meta program to query compile-time information about other program parts while constructing the object program. It allows the meta program to inspect other program pieces to answer questions such as: "what's this variable's type?", "what are the class instances of this type class?", or "which constructors does this data type have and and how do they look like?". The main use case is to generate boilerplate code which ''auto-completes'' manually written code. A prime example is to generically derive type class instances from bare data type definitions.<br />
<br />
Suppose we've defined the following polymorphic data types for representing potentially erroneous values, lists, and binary trees, respectively:<br />
<br />
<haskell><br />
data Result e a = Err e | Ok a<br />
data List a = Nil | Cons a (List a)<br />
data Tree a = Leaf a | Node (Tree a) a (Tree a)<br />
</haskell><br />
<br />
Moreover, suppose we want to derive <code>Functor</code> instances for all of these types. Deriving these instances manually is straightforward, but writing them all out by hand is quite cumbersome. Especially since writing a <code>Functor</code> instance follows the same pattern across all of the above types and in fact any type <code>T a</code>.<br />
<br />
To make a type constructor <code>T</code> an instance of <code>Functor</code>, one needs to implement method <hask>fmap :: (a -> b) -> T a -> T b</hask>. Its definition is hereby precisely determined by parametricity and the functor laws: By parametricity, all values of type <code>a</code> must be replaced according to the provided function with values of type <code>b</code>. Furthermore, by the functor laws, all other shapes of the input value of type <code>T a</code> must be preserved when transforming it to the output value of type <code>T b</code>.<br />
<br />
Meta function <hask>deriveFunctor :: Name -> Q [Dec]</hask> below implements the idea of this algorithm:<br />
<br />
<haskell><br />
data Deriving = Deriving { tyCon :: Name, tyVar :: Name }<br />
<br />
deriveFunctor :: Name -> Q [Dec]<br />
deriveFunctor ty<br />
= do (TyConI tyCon) <- reify ty<br />
(tyConName, tyVars, cs) <- case tyCon of<br />
DataD _ nm tyVars cs _ -> return (nm, tyVars, cs)<br />
NewtypeD _ nm tyVars c _ -> return (nm, tyVars, [c])<br />
_ -> fail "deriveFunctor: tyCon may not be a type synonym."<br />
<br />
let (KindedTV tyVar StarT) = last tyVars<br />
instanceType = conT ''Functor `appT`<br />
(foldl apply (conT tyConName) (init tyVars))<br />
<br />
putQ $ Deriving tyConName tyVar<br />
sequence [instanceD (return []) instanceType [genFmap cs]]<br />
where<br />
apply t (PlainTV name) = appT t (varT name)<br />
apply t (KindedTV name _) = appT t (varT name)<br />
</haskell><br />
<br />
Given the name of a type constructor (e.g. <code>Result</code>, <code>List</code>, etc.), <hask>deriveFunctor</hask> derives the code for this type constructor's <code>Functor</code> instance. For example, running the splice <hask>$(deriveFunctor ''Tree)</hask> generates the following code:<br />
<br />
<haskell><br />
instance Functor Tree where<br />
fmap f (Leaf x) = Leaf (f x)<br />
fmap f (Node l x r) = Node (fmap f l) (f x) (fmap f r)<br />
</haskell><br />
<br />
Meta function <hask>deriveFunctor</hask> shows reification in action. It calls function <hask>reify :: Name -> Q Info</hask> on the input type constructor's name to yield information about this data type's definition. Using <hask>reify</hask>, it thus learns whether the data type was defined using the <code>data</code> or <code>newtype</code> keyword, which constructors it defines and what their shapes are. Based on the learned structure, <hask>deriveFunctor</hask> is then able to generate a suitable definition of <hask>fmap</hask> and its different clauses via the auxiliaries <hask>genFmap</hask>, <hask>genFmapClause</hask>, and <hask>newField</hask>, defined below. These auxiliary definitions generate one <hask>fmap</hask> clause for each of the data type's constructors. And each clause then transforms its constructor by recursively modifying all of the constructor's fields of type <code>a</code> through <hask>fmap</hask>'s function <code>f</code>, while retaining all other shapes.<br />
<br />
<haskell><br />
genFmap :: [Con] -> Q Dec<br />
genFmap cs<br />
= do funD `fmap (map genFmapClause cs)<br />
<br />
genFmapClause :: Con -> Q Clause<br />
genFmapClause c@(NormalC name fieldTypes)<br />
= do f <- newName "f"<br />
fieldNames <- replicateM (length fieldTypes) (newName "x")<br />
<br />
let pats = varP f:[conP name (map varP fieldNames)]<br />
body = normalB $ appsE $<br />
conE name : map (newField f) (zip fieldNames fieldTypes)<br />
<br />
clause pats body []<br />
<br />
newField :: Name -> (Name, StrictType) -> Q Exp<br />
newField f (x, (_, fieldType))<br />
= do Just (Deriving typeCon typeVar) <- getQ<br />
case fieldType of<br />
VarT typeVar' | typeVar' == typeVar -><br />
[| $(varE f) $(varE x) |]<br />
ty `AppT` VarT typeVar' |<br />
leftmost ty == (ConT typeCon) && typeVar' == typeVar -><br />
[| fmap $(varE f) $(varE x) |]<br />
_ -> [| $(varE x) |]<br />
<br />
leftmost :: Type -> Type<br />
leftmost (AppT ty1 _) = leftmost ty1<br />
leftmost ty = ty<br />
</haskell><br />
<br />
In more detail, <hask>deriveFunctor</hask> works as follows. First, via <hask>reify</hask> it observes the input data type's name <hask>tyConName</hask>, its declared type variables <hask>tyVars</hask>, and its exposed constructors <hask>cs</hask>. It then determines the data type's right-most type variable <hask>tyVar</hask> and stores it together with the data type's type constructor name <hask>tyConName</hask> in the <hask>Q</hask> monad's user state. This state information is retrieved later again from inside auxiliary definition <hask>newField</hask>. Next, <hask>deriveFunctor</hask> derives a <hask>Functor</hask>'s <hask>fmap</hask> definition using auxiliary <hask>genFmap</hask>. For each of the input data type's value constructors <hask>cs</hask>, <hask>genFmap</hask> generates an <hask>fmap</hask> clause using helper function <hask>genFmapClause</hask>. The latter recursively maps the provided function <hask>f :: a -> b</hask> over all of a constructor's fields of type <code>a</code>, while leaving all other fields untouched. Each field is hereby modified through <hask>f</hask> or left unchanged by auxiliary <hask>newField</hask> based on the field's type: if a field's type is <code>a</code> (which is stored in the retrieved <hask>tyVar</hask> inside function <hask>newField</hask>), then <hask>f</hask> needs to be applied to it; otherwise it needs to remain unchanged.<br />
<br />
<br />
In an analogous manner to <hask>deriveFunctor</hask>, a function <hask>deriveFoldable :: Name -> Q [Dec]</hask> can be devised to derive a data type's <code>Foldable</code> instance. All that is needed is to provide a definition for function <hask>foldMap :: Monoid m => (a -> m) -> T a -> m</hask>. Again, <hask>foldMap</hask>'s definition follows directly from a data type's bare definition, which can be observed by means of reification. This highlights particularly how the functionality offered by Template Haskell provides a low-level API into the GHC compiler to manipulate abstract syntax trees at compile-time. This mechanism is quite powerful and even allows to simulate some of GHC's offered language extensions, e.g., <code>-XDeriveFunctor</code> and <code>-XDeriveFoldable</code>, to be implemented as a library on top of Template Haskell.<br />
<br />
== Template Haskell for building Embedded Domain specific Languages (EDSLs) ==<br />
<br />
To see Template Haskell's potential for building an EDSL, consider the problem of pattern matching text with regular expressions. Suppose, as part of a Haskell program we need to devise many different regular expressions and use them to pattern match text fragments. Regular expressions are easily defined by an algebraic data type capturing their structure, as well as an evaluator checking whether a regular expression matches some input string. <ref>This example draws on Penn's CIS 552 ''Advanced Programming'' course, specifically Assignment 5: http://www.seas.upenn.edu/~cis552/current/hw/hw05/Main.html.</ref><br />
<br />
<haskell><br />
data RegExp<br />
= Char (Set Char) -- [a], [abc], [a-z]; matches a single character from the specified class<br />
| Alt RegExp RegExp -- r1 | r2 (alternation); matches either r1 or r2<br />
| Seq RegExp RegExp -- r1 r2 (concatenation); matches r1 followed by r2<br />
| Star RegExp -- r* (Kleene star); matches r zero or more times<br />
| Empty -- matches only the empty string<br />
| Void -- matches nothing (always fails)<br />
| Var String -- a variable holding another regexp (explained later)<br />
deriving Show<br />
<br />
match :: RegExp -> String -> Bool<br />
match r s = nullable (foldl deriv r s)<br />
</haskell><br />
<br />
The evaluator <hask>match</hask> is hereby based on the concept of derivatives<ref name="regexp-derivs" />: an initial regular expression <hask>r</hask> matches an input string <hask>s</hask>, if <hask>r</hask> matches the first character of <hask>s</hask> and its derivative regular expression <hask>(deriv r)</hask> matches the remainder of <hask>s</hask>:<br />
<br />
<haskell><br />
nullable :: RegExp -> Bool<br />
nullable (Char _) = False<br />
nullable (Alt r1 r2) = nullable r1 || nullable r2<br />
nullable (Seq r1 r2) = nullable r1 && nullable r2<br />
nullable (Star _) = True<br />
nullable Empty = True<br />
nullable Void = False<br />
nullable (Var _) = False<br />
<br />
deriv :: RegExp -> Char -> RegExp<br />
deriv (Char cs) c<br />
| c `Set.member` cs = Empty<br />
| otherwise = Void<br />
deriv (Alt r1 r2) c = Alt (deriv r1 c) (deriv r2 c)<br />
deriv (Seq r1 r2) c<br />
| nullable r1 = Alt (Seq (deriv r1 c) r2) (deriv r2 c)<br />
| otherwise = Seq (deriv r1 c) r2<br />
deriv (Star r) c = deriv (Alt Empty (Seq r (Star r))) c<br />
deriv Empty _ = Void<br />
deriv Void _ = Void<br />
deriv (Var _) _ = Void<br />
</haskell><br />
<br />
The <code>RegExp</code> data type and the <hask>match</hask> function solve the initially posed problem of providing regular expressions in Haskell. However, specifying regular expressions in abstract syntax is extremely tedious. For example, consider defining a regular expression for checking the wellformedness of email addresses ending with the top level domain '''.com'''. In its usual concrete syntax, such a regular expression is easily defined as <code>([a-z]|[0-9])*@([a-z]|[0-9])*.com</code>, but writing it in terms of the <code>RegExp</code> dataype is verbose and unintuitive. Moreover, parsing functions like<br />
<br />
* <hask>compile :: String -> RegExp</hask>, or<br />
* <hask>compile' :: String -> Either CompileError RegExp</hask><br />
<br />
do not remedy the problem of working with regular expressions in concrete syntax. Due to "compiling" regular expressions at run time, they don't provide any compile-time type-safety guarantees that the input raw expression is wellformed; thus they lead to either run time exceptions for illformed regular expressions (e.g., <hask>compile</hask>) or induce a tedious handling for compiled regexes (e.g., <hask>compile'</hask>).<br />
<br />
To preserve type safety and yet to be able to use regular expressions conveniently, we want to embed the concrete regular expression syntax into the Haskell host language. This can be done via Template Haskell's quasi quotes and furthermore enabling the <code>QuasiQuotes</code> extension. This allows defining ''quasi quotes'' for regular expressions, denoted <code>[regex| .. |]</code>, where anything inside the quasi quote is considered part of an embedded regular expression language. Using quasi quotes, we can then specify the regex for email addresses from above naturally as follows:<br />
<br />
<haskell><br />
validDotComMail :: RegExp<br />
validDotComMail = [regex|([a-z]|[0-9])*@([a-z]|[0-9])*.com|]<br />
</haskell><br />
<br />
We can even compose regular expressions easily from smaller building blocks:<br />
<br />
<haskell><br />
alphaNum, validDotComMail' :: RegExp<br />
alphaNum = [regex|[a-z]|[0-9]|]<br />
validDotComMail' = [regex|${alphaNum}*@${alphaNum}*.com|]<br />
</haskell><br />
<br />
Writing <hask>${alphaNum}</hask> interpolates the regex referred to by <hask>alphaNum</hask> into the larger regex <hask>validDotComMail'</hask>. In essence, this means that we can define our own notion of splicing values from the Haskell meta language into the embedded object language of regular expressions. We can go further and even allow to run Haskell code when interpolating with <code>${..}</code>. For example, refining our wellformedness check for '''.com''' mail addresses, we might want to ensure at least one character to occur on either side of the "@" symbol:<br />
<br />
<haskell><br />
chars, validDotComMail'' :: RegExp<br />
chars = [regex|[a-z]|[A-Z]|[0-9]|[-_.]|]<br />
validDotComMail'' = [regex|${plus chars}@${plus chars}.com|]<br />
<br />
plus :: RegExp -> RegExp<br />
plus r = Seq r (Star r)<br />
</haskell><br />
<br />
Here, <hask>plus</hask> corresponds to the usual regex combinator that requires a given regex to occur at least once. Note how <hask>plus</hask> is defined as a regular Haskell function and then used ''inside'' of the embedded regex language to build the regular expression for <hask>validDotComMail''</hask>.<br />
<br />
Intuitively, a quasi quote like <code>[regex| .. |]</code> converts an embedded language's concrete syntax to Haskell code at compile-time. It is defined by a ''quasi quoter'', which is a parser for the embedded language. Its task is to parse the embedded language's syntax into a corresponding Template Haskell expression and then to splice this expression as real Haskell code in place of the quasi quote. The conversion of embedded language code to corresponding Haskell code hereby happens before typechecking the Haskell module. Hence, trying to splice in malformed embedded language fragments will raise a Haskell type error at compile-time.<br />
<br />
The quasi quoter <code>regex</code> for our embedded language of regular expressions can be defined as follows:<br />
<br />
<haskell><br />
regex :: QuasiQuoter<br />
regex = QuasiQuoter {<br />
quoteExp = compile<br />
, quotePat = notHandled "patterns"<br />
, quoteType = notHandled "types"<br />
, quoteDec = notHandled "declarations"<br />
}<br />
where notHandled things = error $<br />
things ++ " are not handled by the regex quasiquoter."<br />
<br />
compile :: String -> Q Exp<br />
compile s =<br />
case P.parse regexParser "" s of<br />
Left err -> fail (show err)<br />
Right regexp -> [e| regexp |]<br />
</haskell><br />
<br />
That is, formally a <code>QuasiQuoter</code> consists of four parsers,<br />
<br />
<haskell><br />
quoteExp :: String -> Q Exp<br />
quotePat :: String -> Q Pat<br />
quoteType :: String -> Q Type<br />
quoteDec :: String -> Q Dec<br />
</haskell><br />
<br />
to parse raw strings of the embedded language into the different categories of Haskell syntax. In this example, however, we only want to splice embedded regular expressions into the context of Haskell expressions, so we only define the <code>quoteExp</code> parser in the <code>regex</code> quasi quoter. This parser compiles an embedded regular expression given as a string into a corresponding Template Haskell expression.<br />
<br />
Compilation by the <hask>compile</hask> function proceeds in two stages: First, we parse the input string regex into a corresponding <code>RegExp</code> value. Second, we encode this <code>RegExp</code> value as a Haskell expression in Template Haskell's <code>Q Exp</code> type. It is the second step that allows us to interpolate variables (or even code) from the Haskell host language into the EDSL for regular expressions.<br />
<br />
Parsing a raw regular expression into a corresponding <code>RegExp</code> value is a routine task using (e.g.) the ''parsec'' library:<br />
<br />
<haskell><br />
regexParser :: Parsec String () RegExp<br />
regexParser = alts <* eof where<br />
atom = try var <|> char<br />
var = Var <$> (string "${" *> many1 (noneOf "}") <* P.char '}')<br />
char = charclass <|> singlechar<br />
singlechar = (Char . Set.singleton) <$> noneOf specials<br />
charclass = fmap (Char . Set.fromList) $<br />
P.char '[' *> content <* P.char ']'<br />
content = try (concat <$> many1 range)<br />
<|> many1 (noneOf specials)<br />
range = enumFromTo<br />
<$> (noneOf specials <* P.char '-')<br />
<*> noneOf specials<br />
alts = try (Alt <$> seqs <*> (P.char '|' *> alts)) <|> seqs<br />
seqs = try (Seq <$> star <*> seqs) <|> star<br />
star = try (Star <$> (atom <* P.char '*'))<br />
<|> try (Star <$> (P.char '(' *> alts <* string ")*"))<br />
<|> atom<br />
specials = "[]()*|"<br />
</haskell><br />
<br />
To represent regular expressions of type <code>RegExp</code> as Template Haskell expressions of type <code>Q Exp</code>, Template Haskell's <code>Lift</code> typeclass is used. Its method <hask>lift :: Lift a => a -> Q Exp</hask> lifts values from the Haskell meta language (e.g., a <code>RegExp</code> value) into Template Haskell's expression language (i.e., a <code>Q Exp</code> value). The <hask>lift</hask> function is implicitly invoked by quote <hask>[e| regexp |]</hask> in function <code>compile</code>.<br />
<br />
<br />
Most of the lifting is a direct encoding of the syntactic structure of the <code>RegExp</code> value; the only interesting case is when lifting the regular expression variable <hask>Var vars</hask>. In this case, we treat the words in the string <hask>vars</hask> as referring to identifiers from the Haskell host language, which we apply in a left associative manner to each other. Doing this enables interpolation of Haskell identifiers or even simple forms of Haskell expressions into our EDSL of regular expressions as shown by the regexes <hask>validDotComMail'</hask>, and <hask>validDotComMail''</hask> above.<br />
<br />
<haskell><br />
instance Lift a => Lift (Set a) where<br />
lift set = appE (varE `Set.fromList) (lift (Set.toList set))<br />
<br />
instance Lift RegExp where<br />
-- lift :: RegExp -> Q Exp<br />
lift (Char cs) = apply `Char [lift cs]<br />
lift (Alt r1 r2) = apply `Alt (map lift [r1, r2])<br />
lift (Seq r1 r2) = apply `Seq (map lift [r1, r2])<br />
lift (Star r1) = apply `Star (map lift [r1])<br />
lift Empty = apply `Empty []<br />
lift Void = apply `Void []<br />
lift (Var vars) = foldl1 appE $ map (varE . mkName) (words vars)<br />
<br />
apply :: Name -> [Q Exp] -> Q Exp<br />
apply n = foldl appE (conE n)<br />
</haskell><br />
<br />
These two steps constitute the conversion of raw string regular expressions into Template Haskell expressions inside of the <hask>compile</hask> function and define the <code>regex</code> quasiquoter. Whenever we write a quasi quote like <hask>[regex| .. |]</hask> in a Haskell expression context, <hask>regex</hask>'s parser <hask>quoteExp</hask> converts the regex EDSL into a Template Haskell expression <code>Q Exp</code> and splices in the result as a wellformed <code>RegExp</code> value. This example shows how Template Haskell and quasi quotes can be used to define a type-safe, domain specific language for regular expressions.<br />
<br />
=== Shakespearean Templates ===<br />
<br />
In much the same manner as in the last example, Template Haskell and quasi quotes are used in Michael Snoyman's <code>shakespeare</code> library<ref name="shakespeare" /><ref name="shakespeare-lib" />. It defines embedded templating languages for working with the internet's web languages from within a Haskell web application. In particular, the <code>shakespeare</code> library provides the template languages ''Hamlet'', ''Cassius'', and ''Julius'' for writing embedded HTML, CSS, and Javascript code, respectively. All three templating languages internally work quite similarly to the previous example's EDSL for regular expressions: quasi quotes allow one to write HTML, CSS, or JavaScript code in concrete (though slightly modified) syntax inside of Haskell. Moreover, identifiers from the Haskell host language as well as code fragments can be interpolated into the template languages at compile-time. In the remainder we will briefly show-case the <code>shakespeare</code> library's templating language Hamlet for creating HTML documents; the other templating languages Cassius and Julius are similar.<br />
<br />
To create and output a simple web page from inside a Haskell application, the following is enough:<br />
<br />
<haskell><br />
import Data.Text<br />
import Text.Hamlet<br />
import Text.Blaze.Html.Renderer.String<br />
<br />
data Page = Home | About | Github<br />
<br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls Github _ = "https://www.github.com/bollmann"<br />
<br />
webPage :: Text -> Text -> HtmlUrl Page<br />
webPage title content = [hamlet|<br />
<html><br />
<head><br />
<title>#{Text.toUpper title}<br />
<body><br />
<h1>#{title}<br />
<div>Welcome to my Shakespearean Templates page!<br />
<hr><br />
<div>Links:<br />
<ul><br />
<a href=@{Home}>My Homepage<br />
<a href=@{About}>About me<br />
<a href=@{Github}>Check out my Github<br />
<hr><br />
<div>#{content}<br />
|]<br />
<br />
main = putStrLn $ renderHtml $<br />
webPage "Hello Shakespeare!" "Hello World!" mkUrls<br />
</haskell><br />
<br />
Running this Haskell program, outputs an HTML page as specified by the Hamlet templating language, embedded through quasi quote <hask>[hamlet| .. |]</hask> in function <hask>webPage</hask>. Hamlet closely resembles real HTML syntax, but is even more terse: instead of a closing HTML tag, Hamlet uses indentation to indicate the span of the tag. Furthermore, Hamlet allows to interpolate code or identifiers from the Haskell host language when creating an HTML template. Interpolation of Haskell code into Hamlet is done by writing <code>#{ .. }</code>. In the above example, the HTML page's title and content are interpolated from Haskell identifiers. Note particularly how in the webpage's title we uppercase the interpolated title using Haskell's <hask>Text.toUpper</hask> function ''inside'' of the Hamlet language.<br />
<br />
In addition to this standard interpolation, Hamlet can also interpolate links by writing <code>@{..}</code>. These links are specified as values of the <hask>Page</hask> data type inside the template and the <hask>mkUrls</hask> render function translates them to real URLs later. Hamlet's URL interpolation has commonly be phrased as creating "type-safe URLs". One reason is that, just like with normal variable interpolation, all interpolated links have to exist and be type correct at compile-time; in this case, links must be values of the <code>Page</code> data type. Hence, as soon as a link's constructor shape is changed, the compiler statically forces us to update all references to this link as well. Furthermore, there is only one distinct place in the code to maintain or update a link's raw URL, thus minimizing the risk of dead URLs.<br />
<br />
For example, suppose we want to add more external links to our web page. We could model this fact by changing the <hask>Page</hask> data type to<br />
<br />
<haskell><br />
data Page = Home | About | External ExternalPage<br />
data ExternalPage = Github | Haskell | Reddit<br />
</haskell><br />
<br />
and, moreover, changing the <hask>mkUrls</hask> renderer function to account for the new links:<br />
<br />
<haskell><br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls (External page) _ = mkExternalUrls page<br />
<br />
mkExternalUrls :: ExternalPage -> Text<br />
mkExternalUrls Github = "https://www.github.com"<br />
mkExternalUrls Haskell = "http://www.haskell.org"<br />
mkExternalUrls Reddit = "http://www.reddit.com/r/haskell"<br />
</haskell><br />
<br />
Doing just these changes, will then cause a compile-time error in our <hask>webPage</hask> template, since we haven't updated the <hask>Github</hask> reference to our newly adjusted link structure. Hence, the compiler reminds (and in fact forces) us to update all locations in the code that used the old <hask>Github</hask> link to now use the new <hask>External Github</hask> (as well as optionally the <hask>External Haskell</hask>, etc.) links.<br />
<br />
Finally, Hamlet allows to use some control constructs like if conditionals, for loops, and let bindings to embed basic business logic into a webpage's template. Michael Snoyman gives a gentle (and much more in-depth) introduction to shakespearean templates and Yesod<ref name="shakespeare" /><ref name="yesod" />.<br />
<br />
= References =<br />
<br />
<references><br />
<ref name="th1">Tim Sheard and Simon Peyton Jones. Template Meta-Programming for Haskell. SIGPLAN Not., 37(12):60-75, December 2002. URL: https://www.microsoft.com/en-us/research/publication/template-meta-programming-for-haskell/?from=http://research.microsoft.com/~simonpj/papers/meta-haskell/ </ref><br />
<ref name="th2">Tim Sheard and Simon Peyton Jones. Notes on Template Haskell, Version 2. URL: https://www.haskell.org/ghc/docs/papers/th2.ps, 2003.</ref><br />
<ref name="th3">Simon Peyton Jones. Major Proposed Revision of Template Haskell. URL: https://ghc.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposal, 2010</ref><br />
<ref name="qq">Geoffrey Mainland. Why it's nice to be quoted: Quasiquoting for Haskell. In ''Proceedings of the ACM SIGPLAN Workshop on Haskell'', Haskell '07, pages 73-82, New York, NY, USA, 2007. ACM</ref><br />
<ref name="regexp-derivs">Janusz A. Brzozowski. Derivatives of regular expressions. J. ACM, 11(4):481–494, October 1964.</ref><br />
<ref name="shakespeare">Michael Snoyman. Shakespearean Templates. URL: http://www.yesodweb.com/book/shakespearean-templates [Accessed: May 2016].</ref><br />
<ref name="shakespeare-lib">Michael Snoyman. The <code>shakespeare</code> Haskell library. URL: http://hackage.haskell.org/package/shakespeare [Accessed: May 2016].</ref><br />
<ref name="yesod">Michael Snoyman. Haskell and Yesod. URL: http://www.yesodweb.com/book-1.4 [Accessed: May 2016].</ref><br />
<ref name="dep-tys">Daniel Friedlender and Mia Indrika. Do we need Dependent Types? J. Funct. Program. 10(4):409-415, July 2000.</ref><br />
</references></div>Enoksrdhttps://wiki.haskell.org/index.php?title=A_practical_Template_Haskell_Tutorial&diff=62531A practical Template Haskell Tutorial2018-06-21T20:11:06Z<p>Enoksrd: /* Generic Maps */ Fix syntax</p>
<hr />
<div>This tutorial explores the Glasgow Haskell Compiler's compile-time meta programming in Template Haskell. It motivates use cases for meta programming and explains the different Template Haskell features on simple toy programs. The aim is to give an overview of Template Haskell's functionality in an example-driven manner.<br />
<br />
= Introduction =<br />
<br />
Template Haskell (TH) is the standard framework for doing type-safe, compile-time meta programming in the Glasgow Haskell Compiler (GHC). It allows writing Haskell meta programs, which are evaluated at compile-time, and which produce Haskell programs as the results of their execution.<br />
<br />
Template Haskell was conceived by Tim Sheard and Simon Peyton Jones<ref name="th1" /> by drawing on the ideas of Lisp macros, but in the typed setting of Haskell. Since then, the original implementation has evolved quite a bit<ref name="th2" /><ref name="th3" />. Most notably, in 2007 Geoffrey Mainland added support for quasi quoting<ref name="qq" />, which makes the embedding of domain specific languages into the Haskell host language much easier.<br />
<br />
As it exists today, Template Haskell has two main areas of application: Haskell code generation at compile-time and facilitating the embedding of domain specific languages.<br />
<br />
As a code generator, Template Haskell empowers a user to write many, syntactically different, programs all at once by means of a single meta program. All that is needed is a uniform, algorithmic description to create the different result programs. And the meta program then precisely implements the algorithm to compute all the different result programs as its output. This proves useful for example to avoid writing the same repetitive, boilerplate code over and over again. To this end, Template Haskell is used (among many others) in the <code>aeson</code> library to automatically derive a data type's <code>ToJSON</code> and <code>FromJSON</code> instances for JSON serialization; and in the <code>lens</code> library to mechanically create a data type's lenses.<br />
<br />
As a framework for creating domain specific languages (EDSLs), Template Haskell allows a user to embed programs written in another programming language inside of a Haskell program. This enables writing parts of the program in the concrete, domain specific syntax of a different programming language. It has the benefit to think about -- and to express -- domain specific problems in the language best suited for the task. In particular, it lets a user focus on the domain specific problem and removes all additional language burdens induced by inconvenient syntax, unsuited control constructs, etc. Programs from the embedded language are parsed and translated into corresponding (but syntactically heavier) Haskell code at compile-time by Template Haskell. In this sense, (e.g.,) the shakespearean template languages from the <code>shakespeare</code> library use Template Haskell at their core. They expose succinct domain specific languages to write HTML, CSS, and Javascript code inside of a Haskell based web application.<br />
<br />
= Template Haskell by Examples =<br />
<br />
In this section, we will review the Template Haskell features to write meta programs. The first set of examples show-cases Template Haskell's potential as a code generator; the second set of examples highlights its facilities to create embedded domain specific languages (EDSLs). All examples require GHC's language extension <code>TemplateHaskell</code> to be enabled.<br />
<br />
To avoid confusion in the sequel, we distinguish between meta programs and object programs. Meta programs are the Haskell programs that run at compile-time and which generate Template Haskell object programs as the results of their execution; they are the programs that devise or manipulate other programs by some algorithmic means. Object programs, on the other hand, are the Template Haskell programs manipulated and built by the Haskell meta programs at compile-time.<br />
<br />
== Template Haskell as a Code Generator ==<br />
<br />
As an introductory example, consider Haskell's <code>Prelude</code> function <hask>curry :: ((a,b) -> c) -> a -> b -> c</hask>, which converts a function taking a pair to its curried equivalent. Unfortunately, there are no <code>Prelude</code> functions that provide the same currying functionality for functions taking arbitrary <math>n</math>-tuples. Moreover, having to write more than a few of these functions manually is, while trivial, a very repetitive and cumbersome task. Instead we wish to generate needed <hask>curry3</hask>, <hask>curry5</hask>, or <hask>curry8</hask> functions through a single meta program on demand. Template Haskell lets us do just this. The idea is to write a meta function <hask>curryN :: Int -> Q Exp</hask> which, given a number <code>n >= 1</code>, constructs the ''source code'' for an <math>n</math>-ary <hask>curry</hask> function:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import Control.Monad<br />
import Language.Haskell.TH<br />
<br />
curryN :: Int -> Q Exp<br />
curryN n = do<br />
f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
let args = map VarP (f:xs)<br />
ntup = TupE (map VarE xs)<br />
return $ LamE args (AppE (VarE f) ntup)<br />
</haskell><br />
<br />
For input <math>n</math>, meta function <hask>curryN</hask> builds a lambda abstraction <hask>LamE</hask> that pattern matches against a function <hask>f</hask> and <math>n</math> argument variables <hask>x1</hask>, <hask>x2</hask>, ..., <hask>xn</hask>; in its body, it then applies function <hask>f</hask> to the <math>n</math>-tuple <hask>(x1, x2, ..., xn)</hask> derived from the pattern matched variables. The names used to refer to the variables <hask>f</hask> and <hask>x1</hask> through <hask>xn</hask> are generated monadically by function <hask>newName :: String -> Q Name</hask> to always generate fresh names not used anywhere else. Hence, the value returned by <hask>curryN</hask> is a monadic computation of type <code>Q Exp</code>. When executed, this monadic computation yields an expression <code>Exp</code> representing the object program of an <math>n</math>-ary curry function. For example, <hask>(curryN 3)</hask> returns a monadic computation that yields an expression representing a <hask>curry3</hask> function of type <hask>((a, b, c) -> d) -> a -> b -> c -> d</hask> in abstract syntax.<ref>Note that meta function <hask>curryN</hask> cannot be written in normal Haskell per se as the type for a generated <math>n</math>-ary curry function depends on <math>n</math>. Thus, the definition of <hask>curryN</hask> requires ''dependent types'' to be expressed in Haskell, a feature not yet present. However, there already exist ingenious alternatives to "faking" dependent types in Haskell; see for instance [http://www.brics.dk/RS/01/10/ this paper] for a solution to simulate functions like <hask>curryN</hask> without dependent types).</ref><br />
<br />
<br />
To run a meta program like <hask>curryN</hask> at compile-time, we enclose it with Template Haskell's ''splice'' operator <code>$</code> by writing (e.g.,) <hask>$(curryN 3)</hask>. This evaluates the meta program <code>curryN 3</code> and puts the resulting object program <hask>\f x1 x2 x3 -> f (x1, x2, x3)</hask> in place of the splice. In general, the splice operator <code>$</code> can be applied to any monadic <code>Q</code> computation, hereby performing this computation at compile-time and inserting the resulting object program as real Haskell code. To ensure type safety, meta programs to be run are type checked beforehand to indeed yield a valid Template Haskell object program. Hence, only imported, fully-typechecked meta programs can be run via the splice operator <code>$</code>: in particular, we have to evaluate the meta program <code>$(curryN 3)</code> in a separate module to where <code>curryN</code> is defined.<br />
<br />
To generate function declarations for the first <math>n</math> curry functions, we can devise a further meta program on top of <hask>curryN</hask> as follows:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
Running <hask>$(genCurries 20)</hask> will then splice in the first 20 curry functions at compile-time, namely:<br />
<br />
<haskell><br />
curry1 = \ f x1 -> f (x1)<br />
curry2 = \ f x1 x2 -> f (x1, x2)<br />
curry3 = \ f x1 x2 x3 -> f (x1, x2, x3)<br />
curry4 = \ f x1 x2 x3 x4 -> f (x1, x2, x3, x4)<br />
...<br />
curry20 = \ f x1 x2 ... x20 -> f (x1, x2, ..., x20)<br />
</haskell><br />
<br />
Note that in this case, <hask>genCurries</hask> returns a list of top-level function declarations that bind the anonymous lambda abstractions built by <hask>curryN</hask>. Also, to name the function bindings, we use function <hask>mkName :: String -> Name</hask> instead of <hask>newName :: String -> Q Name</hask>. The reason is that here we want to generate functions <hask>curry1</hask> to <hask>curry20</hask> with exactly the prescribed names, so they can be captured and referred to from other parts of the program.<br />
<br />
Evaluating Haskell (meta) programs at compile-time and splicing in the generated object programs as regular Haskell code is the first central building block of Template Haskell. The two other core mechanisms are exhibited by the implementations of <hask>curryN</hask> and <hask>genCurries</hask>: algebraic data types and the quotation monad <code>Q</code>.<br />
<br />
First, object programs created by Template Haskell are represented as regular algebraic data types, describing a program in the form of an abstract syntax tree. The Template Haskell library provides algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> to represent Haskell's surface syntax of expressions, patterns, declarations, and types, respectively. Virtually every concrete Haskell syntactic construct has a corresponding abstract syntax constructor in one of the four ADTs. Furthermore, all Haskell identifiers are represented by the abstract <code>Name</code> data type. By representing object programs as regular algebraic data types (and thus as data), normal Haskell can be used as the meta programming language to build object programs.<br />
<br />
Second, TH object programs are built inside the quotation monad <code>Q</code>. This monad is performed by the splice operator "<code>$</code>" at compile-time as part of evaluating the meta program. In the examples so far, the <code>Q</code> monad was only needed to provide fresh identifiers with function <hask>newName :: String -> Q Name</hask> for the generated Haskell expressions. The other main feature that requires a monadic construction of object programs is ''reification'', which allows to query compile-time information during the object program's construction. We will explain reification in detail later.<br />
<br />
Thus, Template Haskell's core functionality constitutes evaluating object programs with "<code>$</code>" and building them from algebraic data types inside the quotation monad <code>Q</code>. However, constructing object programs in terms of their abstract syntax trees is quite verbose and leads to clumsy meta programs. Therefore the Template Haskell API also provides two further interfaces to build object programs more conveniently: ''syntax construction functions'' and ''quotation brackets''.<br />
<br />
Syntax construction functions directly relate to the syntax constructors from the algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> for representing Haskell code. However, they hide the monadic nature of building object programs. For example, recall our definition of the <hask>genCurries</hask> meta function from above:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
To use the object program generated by the sub call to <hask>curryN</hask> in the larger context of the returned function declaration, we have to first perform <hask>curryN</hask> and bind its result to <hask>cury</hask>. The reason is that we have to account for <hask>curryN</hask>'s generation of fresh names before we can continue. Using syntax construction functions instead of data constructors, however, abstracts from the monadic construction of <hask>genCurries</hask>, thus making its code a little shorter:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = funD name [clause [] (normalB (curryN ith)) []]<br />
where name = mkName $ "curry" ++ show ith<br />
</haskell><br />
<br />
The new <code>funD</code>, <code>clause</code>, and <code>normalB</code> functions directly correspond to the formerly used <code>FunD</code>, <code>Clause</code>, and <code>NormalB</code> constructors. The only difference lies in their types:<br />
<br />
{|<br />
|-<br />
|<hask>FunD :: Name -> [Clause] -> Dec</hask><br />
|<hask>funD :: Name -> [Q Clause] -> Q Dec</hask><br />
|-<br />
|<hask>Clause :: [Pat] -> Body -> Clause</hask><br />
|<hask>clause :: [Q Pat] -> Q Body -> Q Clause</hask><br />
|-<br />
|<hask>NormalB :: Exp -> Body</hask><br />
|<hask>normalB :: Q Exp -> Q Body</hask><br />
|}<br />
<br />
While the syntax constructors work with raw TH expressions, the syntax construction functions expect their monadic counterparts. They construct a TH object program directly in <code>Q</code>, thus freeing the API consumer from doing the monadic wrapping and unwrapping manually. For every syntax constructor, there is a corresponding monadic syntax construction function provided.<br />
<br />
On top of syntax construction functions, quotation brackets are a further shortcut for representing Haskell code. They allow to specify an object program using just regular Haskell syntax by enclosing it inside oxford brackets <code>[| .. |]</code>. That way, object programs can be specified yet much more succinctly. For example, a meta program building a Haskell expression for the identity function is still quite verbose, if expressed with either ADTs or syntax construction functions:<br />
<br />
<haskell><br />
genId :: Q Exp<br />
genId = do<br />
x <- newName "x"<br />
lamE [varP x] (varE x)<br />
</haskell><br />
<br />
Using quotation brackets, writing the same meta program can be abbreviated much further as:<br />
<br />
<haskell><br />
genId' :: Q Exp<br />
genId' = [| \x -> x |]<br />
</haskell><br />
<br />
Quotation brackets quote regular Haskell code as the corresponding object program fragments inside the <code>Q</code> monad. There are quotation brackets for quoting Haskell expressions (<code>[e| .. |]|</code>), patterns (<code>[p| .. |]</code>), declarations (<code>[d| .. |]</code>), and types (<code>[t| .. |]</code>). Writing <code>[| .. |]</code> is hereby just another way of saying <code>[e| .. |]</code>. Using quotation brackets in a sense ''lifts'' Haskell's concrete syntax into corresponding object program expressions inside the <code>Q</code> monad. By doing so, quotation brackets represent the dual of the already introduced splice operator <code>$</code>: Evaluating a meta program with "<code>$</code>" splices in the generated object program as real Haskell code; in contrast, quotation brackets <code>[| .. |]</code> turn real Haskell code into an object program. Consequently, quotation brackets and the splice operator cancel each other out. The equation <code>$([| e |]) = e</code> holds for all expressions <code>e</code> and similar equations hold for declarations, and types<ref name="th2" />.<br />
<br />
In addition, there is support for quoting Haskell (value and type) identifiers as corresponding <code>Name</code>s inside Template Haskell. This allows to refer to regular Haskell identifiers from within TH object programs. For example, writing <hask>'genId</hask> yields a TH <code>Name</code> referring to the <hask>genId</hask> identifier. Similarly, <hask>''Q</hask> gives a <code>Name</code> referring to the <code>Q</code> type identifier.<br />
<br />
=== Generic Maps ===<br />
<br />
As a second example that uses both syntax construction functions as well as quotation brackets, let's consider a meta program <hask>mapN :: Int -> Q Dec</hask> to build "generic" <hask>map</hask> functions at compile-time. Invoking <hask>$(mapN 1)</hask> should generate the well-known standard function <hask>map :: (a -> b) -> [a] -> [b]</hask>; evaluating <hask>$(mapN 2)</hask> should splice in a binary map function of type <hask>(a -> b -> c) -> [a] -> [b] -> [c]</hask>, and so on.<ref>Note that <math>n</math>-ary maps are better written using Applicative Functors and <code>ZipList</code>s, as this allows to define them first-class from within regular Haskell. For understanding Template Haskell as a code generator, this example is still useful though.</ref><br />
<br />
<haskell><br />
mapN :: Int -> Q Dec<br />
mapN n<br />
| n >= 1 = funD name [cl1, cl2]<br />
| otherwise = fail "mapN: argument n may not be <= 0."<br />
where<br />
name = mkName $ "map" ++ show n<br />
cl1 = do f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
ys <- replicateM n (newName "ys")<br />
let argPatts = varP f : consPatts<br />
consPatts = [ [p| $(varP x) : $(varP ys) |]<br />
| (x,ys) <- xs `zip` ys ]<br />
apply = foldl (\ g x -> [| $g $(varE x) |])<br />
first = apply (varE f) xs<br />
rest = apply (varE name) (f:ys)<br />
clause argPatts (normalB [| $first : $rest |]) []<br />
cl2 = clause (replicate (n+1) wildP) (normalB (conE '[])) []<br />
</haskell><br />
<br />
The implementation of <hask>mapN</hask> is very much in the spirit of meta function <hask>curryN</hask> from the first example. For instance, evaluating splice <hask>$(mapN 3)</hask> splices in the following map function at compile-time:<br />
<br />
<haskell><br />
map3 f (x:xs) (y:ys) (z:zs) = f x y z : map3 f xs ys zs<br />
map3 _ _ _ _ = []<br />
</haskell><br />
<br />
Nonetheless, meta function <hask>mapN</hask> exhibits a couple of new Template Haskell features: First, quotation brackets and splices are used in several places to abbreviate the object program construction. For example, helper definition <hask>apply</hask> used to generate <hask>map3</hask>'s body <hask>f x y z : map3 f xs ys zs</hask> shows the use of quotation brackets; it also highlights how splicing (<hask>$</hask>) and quotes (<hask>[| .. |]</hask>) cancel each other out. Second, identifier quotes (namely, <hask>'[]</hask>) are used to create an object program <code>Name</code> that refers to Haskell's built-in list constructor <hask>[]</hask>. Third, the example advertises how all three APIs for building Template Haskell object programs can be interleaved. The lowermost verbose API of building a raw TH data value inside the quotation monad <code>Q</code> can be abbreviated, where possible, with syntax constructor functions and quotation brackets.<br />
<br />
Lastly, the <hask>mapN</hask> example exemplifies how Haskell's static scoping is extended to object programs. The scoping principle for object programs is just as in normal Haskell: Identifiers are bound to their lexically enclosing binders in scope at the point the object program is ''defined''. Quotation brackets and splices don't alter static scopes, even though splices may bring an object program into scope at a location, where a conflicting closure is present. For example, consider this snippet:<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
static :: Q Exp<br />
static = [| x |]<br />
<br />
plus42 :: Int -> Int<br />
plus42 x = $static + x<br />
</haskell><br />
<br />
Here the occurrence of <hask>x</hask> in <hask>static</hask> refers to the global identifier <hask>x</hask> that is lexically in scope during its definition. Splicing in <hask>static</hask> into a different scope later where a different local <hask>x</hask> is present (i.e., <hask>plus42</hask>'s local identifier <hask>x</hask>), doesn't alter the link between <hask>static</hask>'s <hask>x</hask> and the global identifier <hask>x</hask>.<br />
<br />
The only exception to static scoping in Template Haskell are the names generated by <hask>mkName :: String -> Name</hask>. These names implement dynamic scoping and ''can'' be captured in spliced-in code. Changing the previous snippet to<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
dynamic :: Q Exp<br />
dynamic = VarE (mkName "x")<br />
<br />
times2 :: Int -> Int<br />
times2 x = $dynamic + x<br />
</haskell><br />
<br />
results in the identifier <hask>x</hask> spliced in by <hask>$dynamic</hask> to be bound to the closest <hask>x</hask> in scope. Hence, its binder is <hask>times2</hask>'s local identifier <hask>x</hask> and ''not'' the global <hask>x</hask>.<br />
<br />
=== Reification ===<br />
<br />
The final major Template Haskell feature not yet described is program ''reification''. Briefly, reification allows a meta program to query compile-time information about other program parts while constructing the object program. It allows the meta program to inspect other program pieces to answer questions such as: "what's this variable's type?", "what are the class instances of this type class?", or "which constructors does this data type have and and how do they look like?". The main use case is to generate boilerplate code which ''auto-completes'' manually written code. A prime example is to generically derive type class instances from bare data type definitions.<br />
<br />
Suppose we've defined the following polymorphic data types for representing potentially erroneous values, lists, and binary trees, respectively:<br />
<br />
<haskell><br />
data Result e a = Err e | Ok a<br />
data List a = Nil | Cons a (List a)<br />
data Tree a = Leaf a | Node (Tree a) a (Tree a)<br />
</haskell><br />
<br />
Moreover, suppose we want to derive <code>Functor</code> instances for all of these types. Deriving these instances manually is straightforward, but writing them all out by hand is quite cumbersome. Especially since writing a <code>Functor</code> instance follows the same pattern across all of the above types and in fact any type <code>T a</code>.<br />
<br />
To make a type constructor <code>T</code> an instance of <code>Functor</code>, one needs to implement method <hask>fmap :: (a -> b) -> T a -> T b</hask>. Its definition is hereby precisely determined by parametricity and the functor laws: By parametricity, all values of type <code>a</code> must be replaced according to the provided function with values of type <code>b</code>. Furthermore, by the functor laws, all other shapes of the input value of type <code>T a</code> must be preserved when transforming it to the output value of type <code>T b</code>.<br />
<br />
Meta function <hask>deriveFunctor :: Name -> Q [Dec]</hask> below implements the idea of this algorithm:<br />
<br />
<haskell><br />
data Deriving = Deriving { tyCon :: Name, tyVar :: Name }<br />
<br />
deriveFunctor :: Name -> Q [Dec]<br />
deriveFunctor ty<br />
= do (TyConI tyCon) <- reify ty<br />
(tyConName, tyVars, cs) <- case tyCon of<br />
DataD _ nm tyVars cs _ -> return (nm, tyVars, cs)<br />
NewtypeD _ nm tyVars c _ -> return (nm, tyVars, [c])<br />
_ -> fail "deriveFunctor: tyCon may not be a type synonym."<br />
<br />
let (KindedTV tyVar StarT) = last tyVars<br />
instanceType = conT ``Functor `appT`<br />
(foldl apply (conT tyConName) (init tyVars))<br />
<br />
putQ $ Deriving tyConName tyVar<br />
sequence [instanceD (return []) instanceType [genFmap cs]]<br />
where<br />
apply t (PlainTV name) = appT t (varT name)<br />
apply t (KindedTV name _) = appT t (varT name)<br />
</haskell><br />
<br />
Given the name of a type constructor (e.g. <code>Result</code>, <code>List</code>, etc.), <hask>deriveFunctor</hask> derives the code for this type constructor's <code>Functor</code> instance. For example, running the splice <hask>$(deriveFunctor ''Tree)</hask> generates the following code:<br />
<br />
<haskell><br />
instance Functor Tree where<br />
fmap f (Leaf x) = Leaf (f x)<br />
fmap f (Node l x r) = Node (fmap f l) (f x) (fmap f r)<br />
</haskell><br />
<br />
Meta function <hask>deriveFunctor</hask> shows reification in action. It calls function <hask>reify :: Name -> Q Info</hask> on the input type constructor's name to yield information about this data type's definition. Using <hask>reify</hask>, it thus learns whether the data type was defined using the <code>data</code> or <code>newtype</code> keyword, which constructors it defines and what their shapes are. Based on the learned structure, <hask>deriveFunctor</hask> is then able to generate a suitable definition of <hask>fmap</hask> and its different clauses via the auxiliaries <hask>genFmap</hask>, <hask>genFmapClause</hask>, and <hask>newField</hask>, defined below. These auxiliary definitions generate one <hask>fmap</hask> clause for each of the data type's constructors. And each clause then transforms its constructor by recursively modifying all of the constructor's fields of type <code>a</code> through <hask>fmap</hask>'s function <code>f</code>, while retaining all other shapes.<br />
<br />
<haskell><br />
genFmap :: [Con] -> Q Dec<br />
genFmap cs<br />
= do funD `fmap (map genFmapClause cs)<br />
<br />
genFmapClause :: Con -> Q Clause<br />
genFmapClause c@(NormalC name fieldTypes)<br />
= do f <- newName "f"<br />
fieldNames <- replicateM (length fieldTypes) (newName "x")<br />
<br />
let pats = varP f:[conP name (map varP fieldNames)]<br />
body = normalB $ appsE $<br />
conE name : map (newField f) (zip fieldNames fieldTypes)<br />
<br />
clause pats body []<br />
<br />
newField :: Name -> (Name, StrictType) -> Q Exp<br />
newField f (x, (_, fieldType))<br />
= do Just (Deriving typeCon typeVar) <- getQ<br />
case fieldType of<br />
VarT typeVar' | typeVar' == typeVar -><br />
[| $(varE f) $(varE x) |]<br />
ty `AppT` VarT typeVar' |<br />
leftmost ty == (ConT typeCon) && typeVar' == typeVar -><br />
[| fmap $(varE f) $(varE x) |]<br />
_ -> [| $(varE x) |]<br />
<br />
leftmost :: Type -> Type<br />
leftmost (AppT ty1 _) = leftmost ty1<br />
leftmost ty = ty<br />
</haskell><br />
<br />
In more detail, <hask>deriveFunctor</hask> works as follows. First, via <hask>reify</hask> it observes the input data type's name <hask>tyConName</hask>, its declared type variables <hask>tyVars</hask>, and its exposed constructors <hask>cs</hask>. It then determines the data type's right-most type variable <hask>tyVar</hask> and stores it together with the data type's type constructor name <hask>tyConName</hask> in the <hask>Q</hask> monad's user state. This state information is retrieved later again from inside auxiliary definition <hask>newField</hask>. Next, <hask>deriveFunctor</hask> derives a <hask>Functor</hask>'s <hask>fmap</hask> definition using auxiliary <hask>genFmap</hask>. For each of the input data type's value constructors <hask>cs</hask>, <hask>genFmap</hask> generates an <hask>fmap</hask> clause using helper function <hask>genFmapClause</hask>. The latter recursively maps the provided function <hask>f :: a -> b</hask> over all of a constructor's fields of type <code>a</code>, while leaving all other fields untouched. Each field is hereby modified through <hask>f</hask> or left unchanged by auxiliary <hask>newField</hask> based on the field's type: if a field's type is <code>a</code> (which is stored in the retrieved <hask>tyVar</hask> inside function <hask>newField</hask>), then <hask>f</hask> needs to be applied to it; otherwise it needs to remain unchanged.<br />
<br />
<br />
In an analogous manner to <hask>deriveFunctor</hask>, a function <hask>deriveFoldable :: Name -> Q [Dec]</hask> can be devised to derive a data type's <code>Foldable</code> instance. All that is needed is to provide a definition for function <hask>foldMap :: Monoid m => (a -> m) -> T a -> m</hask>. Again, <hask>foldMap</hask>'s definition follows directly from a data type's bare definition, which can be observed by means of reification. This highlights particularly how the functionality offered by Template Haskell provides a low-level API into the GHC compiler to manipulate abstract syntax trees at compile-time. This mechanism is quite powerful and even allows to simulate some of GHC's offered language extensions, e.g., <code>-XDeriveFunctor</code> and <code>-XDeriveFoldable</code>, to be implemented as a library on top of Template Haskell.<br />
<br />
== Template Haskell for building Embedded Domain specific Languages (EDSLs) ==<br />
<br />
To see Template Haskell's potential for building an EDSL, consider the problem of pattern matching text with regular expressions. Suppose, as part of a Haskell program we need to devise many different regular expressions and use them to pattern match text fragments. Regular expressions are easily defined by an algebraic data type capturing their structure, as well as an evaluator checking whether a regular expression matches some input string. <ref>This example draws on Penn's CIS 552 ''Advanced Programming'' course, specifically Assignment 5: http://www.seas.upenn.edu/~cis552/current/hw/hw05/Main.html.</ref><br />
<br />
<haskell><br />
data RegExp<br />
= Char (Set Char) -- [a], [abc], [a-z]; matches a single character from the specified class<br />
| Alt RegExp RegExp -- r1 | r2 (alternation); matches either r1 or r2<br />
| Seq RegExp RegExp -- r1 r2 (concatenation); matches r1 followed by r2<br />
| Star RegExp -- r* (Kleene star); matches r zero or more times<br />
| Empty -- matches only the empty string<br />
| Void -- matches nothing (always fails)<br />
| Var String -- a variable holding another regexp (explained later)<br />
deriving Show<br />
<br />
match :: RegExp -> String -> Bool<br />
match r s = nullable (foldl deriv r s)<br />
</haskell><br />
<br />
The evaluator <hask>match</hask> is hereby based on the concept of derivatives<ref name="regexp-derivs" />: an initial regular expression <hask>r</hask> matches an input string <hask>s</hask>, if <hask>r</hask> matches the first character of <hask>s</hask> and its derivative regular expression <hask>(deriv r)</hask> matches the remainder of <hask>s</hask>:<br />
<br />
<haskell><br />
nullable :: RegExp -> Bool<br />
nullable (Char _) = False<br />
nullable (Alt r1 r2) = nullable r1 || nullable r2<br />
nullable (Seq r1 r2) = nullable r1 && nullable r2<br />
nullable (Star _) = True<br />
nullable Empty = True<br />
nullable Void = False<br />
nullable (Var _) = False<br />
<br />
deriv :: RegExp -> Char -> RegExp<br />
deriv (Char cs) c<br />
| c `Set.member` cs = Empty<br />
| otherwise = Void<br />
deriv (Alt r1 r2) c = Alt (deriv r1 c) (deriv r2 c)<br />
deriv (Seq r1 r2) c<br />
| nullable r1 = Alt (Seq (deriv r1 c) r2) (deriv r2 c)<br />
| otherwise = Seq (deriv r1 c) r2<br />
deriv (Star r) c = deriv (Alt Empty (Seq r (Star r))) c<br />
deriv Empty _ = Void<br />
deriv Void _ = Void<br />
deriv (Var _) _ = Void<br />
</haskell><br />
<br />
The <code>RegExp</code> data type and the <hask>match</hask> function solve the initially posed problem of providing regular expressions in Haskell. However, specifying regular expressions in abstract syntax is extremely tedious. For example, consider defining a regular expression for checking the wellformedness of email addresses ending with the top level domain '''.com'''. In its usual concrete syntax, such a regular expression is easily defined as <code>([a-z]|[0-9])*@([a-z]|[0-9])*.com</code>, but writing it in terms of the <code>RegExp</code> dataype is verbose and unintuitive. Moreover, parsing functions like<br />
<br />
* <hask>compile :: String -> RegExp</hask>, or<br />
* <hask>compile' :: String -> Either CompileError RegExp</hask><br />
<br />
do not remedy the problem of working with regular expressions in concrete syntax. Due to "compiling" regular expressions at run time, they don't provide any compile-time type-safety guarantees that the input raw expression is wellformed; thus they lead to either run time exceptions for illformed regular expressions (e.g., <hask>compile</hask>) or induce a tedious handling for compiled regexes (e.g., <hask>compile'</hask>).<br />
<br />
To preserve type safety and yet to be able to use regular expressions conveniently, we want to embed the concrete regular expression syntax into the Haskell host language. This can be done via Template Haskell's quasi quotes and furthermore enabling the <code>QuasiQuotes</code> extension. This allows defining ''quasi quotes'' for regular expressions, denoted <code>[regex| .. |]</code>, where anything inside the quasi quote is considered part of an embedded regular expression language. Using quasi quotes, we can then specify the regex for email addresses from above naturally as follows:<br />
<br />
<haskell><br />
validDotComMail :: RegExp<br />
validDotComMail = [regex|([a-z]|[0-9])*@([a-z]|[0-9])*.com|]<br />
</haskell><br />
<br />
We can even compose regular expressions easily from smaller building blocks:<br />
<br />
<haskell><br />
alphaNum, validDotComMail' :: RegExp<br />
alphaNum = [regex|[a-z]|[0-9]|]<br />
validDotComMail' = [regex|${alphaNum}*@${alphaNum}*.com|]<br />
</haskell><br />
<br />
Writing <hask>${alphaNum}</hask> interpolates the regex referred to by <hask>alphaNum</hask> into the larger regex <hask>validDotComMail'</hask>. In essence, this means that we can define our own notion of splicing values from the Haskell meta language into the embedded object language of regular expressions. We can go further and even allow to run Haskell code when interpolating with <code>${..}</code>. For example, refining our wellformedness check for '''.com''' mail addresses, we might want to ensure at least one character to occur on either side of the "@" symbol:<br />
<br />
<haskell><br />
chars, validDotComMail'' :: RegExp<br />
chars = [regex|[a-z]|[A-Z]|[0-9]|[-_.]|]<br />
validDotComMail'' = [regex|${plus chars}@${plus chars}.com|]<br />
<br />
plus :: RegExp -> RegExp<br />
plus r = Seq r (Star r)<br />
</haskell><br />
<br />
Here, <hask>plus</hask> corresponds to the usual regex combinator that requires a given regex to occur at least once. Note how <hask>plus</hask> is defined as a regular Haskell function and then used ''inside'' of the embedded regex language to build the regular expression for <hask>validDotComMail''</hask>.<br />
<br />
Intuitively, a quasi quote like <code>[regex| .. |]</code> converts an embedded language's concrete syntax to Haskell code at compile-time. It is defined by a ''quasi quoter'', which is a parser for the embedded language. Its task is to parse the embedded language's syntax into a corresponding Template Haskell expression and then to splice this expression as real Haskell code in place of the quasi quote. The conversion of embedded language code to corresponding Haskell code hereby happens before typechecking the Haskell module. Hence, trying to splice in malformed embedded language fragments will raise a Haskell type error at compile-time.<br />
<br />
The quasi quoter <code>regex</code> for our embedded language of regular expressions can be defined as follows:<br />
<br />
<haskell><br />
regex :: QuasiQuoter<br />
regex = QuasiQuoter {<br />
quoteExp = compile<br />
, quotePat = notHandled "patterns"<br />
, quoteType = notHandled "types"<br />
, quoteDec = notHandled "declarations"<br />
}<br />
where notHandled things = error $<br />
things ++ " are not handled by the regex quasiquoter."<br />
<br />
compile :: String -> Q Exp<br />
compile s =<br />
case P.parse regexParser "" s of<br />
Left err -> fail (show err)<br />
Right regexp -> [e| regexp |]<br />
</haskell><br />
<br />
That is, formally a <code>QuasiQuoter</code> consists of four parsers,<br />
<br />
<haskell><br />
quoteExp :: String -> Q Exp<br />
quotePat :: String -> Q Pat<br />
quoteType :: String -> Q Type<br />
quoteDec :: String -> Q Dec<br />
</haskell><br />
<br />
to parse raw strings of the embedded language into the different categories of Haskell syntax. In this example, however, we only want to splice embedded regular expressions into the context of Haskell expressions, so we only define the <code>quoteExp</code> parser in the <code>regex</code> quasi quoter. This parser compiles an embedded regular expression given as a string into a corresponding Template Haskell expression.<br />
<br />
Compilation by the <hask>compile</hask> function proceeds in two stages: First, we parse the input string regex into a corresponding <code>RegExp</code> value. Second, we encode this <code>RegExp</code> value as a Haskell expression in Template Haskell's <code>Q Exp</code> type. It is the second step that allows us to interpolate variables (or even code) from the Haskell host language into the EDSL for regular expressions.<br />
<br />
Parsing a raw regular expression into a corresponding <code>RegExp</code> value is a routine task using (e.g.) the ''parsec'' library:<br />
<br />
<haskell><br />
regexParser :: Parsec String () RegExp<br />
regexParser = alts <* eof where<br />
atom = try var <|> char<br />
var = Var <$> (string "${" *> many1 (noneOf "}") <* P.char '}')<br />
char = charclass <|> singlechar<br />
singlechar = (Char . Set.singleton) <$> noneOf specials<br />
charclass = fmap (Char . Set.fromList) $<br />
P.char '[' *> content <* P.char ']'<br />
content = try (concat <$> many1 range)<br />
<|> many1 (noneOf specials)<br />
range = enumFromTo<br />
<$> (noneOf specials <* P.char '-')<br />
<*> noneOf specials<br />
alts = try (Alt <$> seqs <*> (P.char '|' *> alts)) <|> seqs<br />
seqs = try (Seq <$> star <*> seqs) <|> star<br />
star = try (Star <$> (atom <* P.char '*'))<br />
<|> try (Star <$> (P.char '(' *> alts <* string ")*"))<br />
<|> atom<br />
specials = "[]()*|"<br />
</haskell><br />
<br />
To represent regular expressions of type <code>RegExp</code> as Template Haskell expressions of type <code>Q Exp</code>, Template Haskell's <code>Lift</code> typeclass is used. Its method <hask>lift :: Lift a => a -> Q Exp</hask> lifts values from the Haskell meta language (e.g., a <code>RegExp</code> value) into Template Haskell's expression language (i.e., a <code>Q Exp</code> value). The <hask>lift</hask> function is implicitly invoked by quote <hask>[e| regexp |]</hask> in function <code>compile</code>.<br />
<br />
<br />
Most of the lifting is a direct encoding of the syntactic structure of the <code>RegExp</code> value; the only interesting case is when lifting the regular expression variable <hask>Var vars</hask>. In this case, we treat the words in the string <hask>vars</hask> as referring to identifiers from the Haskell host language, which we apply in a left associative manner to each other. Doing this enables interpolation of Haskell identifiers or even simple forms of Haskell expressions into our EDSL of regular expressions as shown by the regexes <hask>validDotComMail'</hask>, and <hask>validDotComMail''</hask> above.<br />
<br />
<haskell><br />
instance Lift a => Lift (Set a) where<br />
lift set = appE (varE `Set.fromList) (lift (Set.toList set))<br />
<br />
instance Lift RegExp where<br />
-- lift :: RegExp -> Q Exp<br />
lift (Char cs) = apply `Char [lift cs]<br />
lift (Alt r1 r2) = apply `Alt (map lift [r1, r2])<br />
lift (Seq r1 r2) = apply `Seq (map lift [r1, r2])<br />
lift (Star r1) = apply `Star (map lift [r1])<br />
lift Empty = apply `Empty []<br />
lift Void = apply `Void []<br />
lift (Var vars) = foldl1 appE $ map (varE . mkName) (words vars)<br />
<br />
apply :: Name -> [Q Exp] -> Q Exp<br />
apply n = foldl appE (conE n)<br />
</haskell><br />
<br />
These two steps constitute the conversion of raw string regular expressions into Template Haskell expressions inside of the <hask>compile</hask> function and define the <code>regex</code> quasiquoter. Whenever we write a quasi quote like <hask>[regex| .. |]</hask> in a Haskell expression context, <hask>regex</hask>'s parser <hask>quoteExp</hask> converts the regex EDSL into a Template Haskell expression <code>Q Exp</code> and splices in the result as a wellformed <code>RegExp</code> value. This example shows how Template Haskell and quasi quotes can be used to define a type-safe, domain specific language for regular expressions.<br />
<br />
=== Shakespearean Templates ===<br />
<br />
In much the same manner as in the last example, Template Haskell and quasi quotes are used in Michael Snoyman's <code>shakespeare</code> library<ref name="shakespeare" /><ref name="shakespeare-lib" />. It defines embedded templating languages for working with the internet's web languages from within a Haskell web application. In particular, the <code>shakespeare</code> library provides the template languages ''Hamlet'', ''Cassius'', and ''Julius'' for writing embedded HTML, CSS, and Javascript code, respectively. All three templating languages internally work quite similarly to the previous example's EDSL for regular expressions: quasi quotes allow one to write HTML, CSS, or JavaScript code in concrete (though slightly modified) syntax inside of Haskell. Moreover, identifiers from the Haskell host language as well as code fragments can be interpolated into the template languages at compile-time. In the remainder we will briefly show-case the <code>shakespeare</code> library's templating language Hamlet for creating HTML documents; the other templating languages Cassius and Julius are similar.<br />
<br />
To create and output a simple web page from inside a Haskell application, the following is enough:<br />
<br />
<haskell><br />
import Data.Text<br />
import Text.Hamlet<br />
import Text.Blaze.Html.Renderer.String<br />
<br />
data Page = Home | About | Github<br />
<br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls Github _ = "https://www.github.com/bollmann"<br />
<br />
webPage :: Text -> Text -> HtmlUrl Page<br />
webPage title content = [hamlet|<br />
<html><br />
<head><br />
<title>#{Text.toUpper title}<br />
<body><br />
<h1>#{title}<br />
<div>Welcome to my Shakespearean Templates page!<br />
<hr><br />
<div>Links:<br />
<ul><br />
<a href=@{Home}>My Homepage<br />
<a href=@{About}>About me<br />
<a href=@{Github}>Check out my Github<br />
<hr><br />
<div>#{content}<br />
|]<br />
<br />
main = putStrLn $ renderHtml $<br />
webPage "Hello Shakespeare!" "Hello World!" mkUrls<br />
</haskell><br />
<br />
Running this Haskell program, outputs an HTML page as specified by the Hamlet templating language, embedded through quasi quote <hask>[hamlet| .. |]</hask> in function <hask>webPage</hask>. Hamlet closely resembles real HTML syntax, but is even more terse: instead of a closing HTML tag, Hamlet uses indentation to indicate the span of the tag. Furthermore, Hamlet allows to interpolate code or identifiers from the Haskell host language when creating an HTML template. Interpolation of Haskell code into Hamlet is done by writing <code>#{ .. }</code>. In the above example, the HTML page's title and content are interpolated from Haskell identifiers. Note particularly how in the webpage's title we uppercase the interpolated title using Haskell's <hask>Text.toUpper</hask> function ''inside'' of the Hamlet language.<br />
<br />
In addition to this standard interpolation, Hamlet can also interpolate links by writing <code>@{..}</code>. These links are specified as values of the <hask>Page</hask> data type inside the template and the <hask>mkUrls</hask> render function translates them to real URLs later. Hamlet's URL interpolation has commonly be phrased as creating "type-safe URLs". One reason is that, just like with normal variable interpolation, all interpolated links have to exist and be type correct at compile-time; in this case, links must be values of the <code>Page</code> data type. Hence, as soon as a link's constructor shape is changed, the compiler statically forces us to update all references to this link as well. Furthermore, there is only one distinct place in the code to maintain or update a link's raw URL, thus minimizing the risk of dead URLs.<br />
<br />
For example, suppose we want to add more external links to our web page. We could model this fact by changing the <hask>Page</hask> data type to<br />
<br />
<haskell><br />
data Page = Home | About | External ExternalPage<br />
data ExternalPage = Github | Haskell | Reddit<br />
</haskell><br />
<br />
and, moreover, changing the <hask>mkUrls</hask> renderer function to account for the new links:<br />
<br />
<haskell><br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls (External page) _ = mkExternalUrls page<br />
<br />
mkExternalUrls :: ExternalPage -> Text<br />
mkExternalUrls Github = "https://www.github.com"<br />
mkExternalUrls Haskell = "http://www.haskell.org"<br />
mkExternalUrls Reddit = "http://www.reddit.com/r/haskell"<br />
</haskell><br />
<br />
Doing just these changes, will then cause a compile-time error in our <hask>webPage</hask> template, since we haven't updated the <hask>Github</hask> reference to our newly adjusted link structure. Hence, the compiler reminds (and in fact forces) us to update all locations in the code that used the old <hask>Github</hask> link to now use the new <hask>External Github</hask> (as well as optionally the <hask>External Haskell</hask>, etc.) links.<br />
<br />
Finally, Hamlet allows to use some control constructs like if conditionals, for loops, and let bindings to embed basic business logic into a webpage's template. Michael Snoyman gives a gentle (and much more in-depth) introduction to shakespearean templates and Yesod<ref name="shakespeare" /><ref name="yesod" />.<br />
<br />
= References =<br />
<br />
<references><br />
<ref name="th1">Tim Sheard and Simon Peyton Jones. Template Meta-Programming for Haskell. SIGPLAN Not., 37(12):60-75, December 2002. URL: https://www.microsoft.com/en-us/research/publication/template-meta-programming-for-haskell/?from=http://research.microsoft.com/~simonpj/papers/meta-haskell/ </ref><br />
<ref name="th2">Tim Sheard and Simon Peyton Jones. Notes on Template Haskell, Version 2. URL: https://www.haskell.org/ghc/docs/papers/th2.ps, 2003.</ref><br />
<ref name="th3">Simon Peyton Jones. Major Proposed Revision of Template Haskell. URL: https://ghc.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposal, 2010</ref><br />
<ref name="qq">Geoffrey Mainland. Why it's nice to be quoted: Quasiquoting for Haskell. In ''Proceedings of the ACM SIGPLAN Workshop on Haskell'', Haskell '07, pages 73-82, New York, NY, USA, 2007. ACM</ref><br />
<ref name="regexp-derivs">Janusz A. Brzozowski. Derivatives of regular expressions. J. ACM, 11(4):481–494, October 1964.</ref><br />
<ref name="shakespeare">Michael Snoyman. Shakespearean Templates. URL: http://www.yesodweb.com/book/shakespearean-templates [Accessed: May 2016].</ref><br />
<ref name="shakespeare-lib">Michael Snoyman. The <code>shakespeare</code> Haskell library. URL: http://hackage.haskell.org/package/shakespeare [Accessed: May 2016].</ref><br />
<ref name="yesod">Michael Snoyman. Haskell and Yesod. URL: http://www.yesodweb.com/book-1.4 [Accessed: May 2016].</ref><br />
<ref name="dep-tys">Daniel Friedlender and Mia Indrika. Do we need Dependent Types? J. Funct. Program. 10(4):409-415, July 2000.</ref><br />
</references></div>Enoksrdhttps://wiki.haskell.org/index.php?title=A_practical_Template_Haskell_Tutorial&diff=62530A practical Template Haskell Tutorial2018-06-21T20:00:13Z<p>Enoksrd: /* References */ Fix TH notes reference URL and add TH paper reference URL</p>
<hr />
<div>This tutorial explores the Glasgow Haskell Compiler's compile-time meta programming in Template Haskell. It motivates use cases for meta programming and explains the different Template Haskell features on simple toy programs. The aim is to give an overview of Template Haskell's functionality in an example-driven manner.<br />
<br />
= Introduction =<br />
<br />
Template Haskell (TH) is the standard framework for doing type-safe, compile-time meta programming in the Glasgow Haskell Compiler (GHC). It allows writing Haskell meta programs, which are evaluated at compile-time, and which produce Haskell programs as the results of their execution.<br />
<br />
Template Haskell was conceived by Tim Sheard and Simon Peyton Jones<ref name="th1" /> by drawing on the ideas of Lisp macros, but in the typed setting of Haskell. Since then, the original implementation has evolved quite a bit<ref name="th2" /><ref name="th3" />. Most notably, in 2007 Geoffrey Mainland added support for quasi quoting<ref name="qq" />, which makes the embedding of domain specific languages into the Haskell host language much easier.<br />
<br />
As it exists today, Template Haskell has two main areas of application: Haskell code generation at compile-time and facilitating the embedding of domain specific languages.<br />
<br />
As a code generator, Template Haskell empowers a user to write many, syntactically different, programs all at once by means of a single meta program. All that is needed is a uniform, algorithmic description to create the different result programs. And the meta program then precisely implements the algorithm to compute all the different result programs as its output. This proves useful for example to avoid writing the same repetitive, boilerplate code over and over again. To this end, Template Haskell is used (among many others) in the <code>aeson</code> library to automatically derive a data type's <code>ToJSON</code> and <code>FromJSON</code> instances for JSON serialization; and in the <code>lens</code> library to mechanically create a data type's lenses.<br />
<br />
As a framework for creating domain specific languages (EDSLs), Template Haskell allows a user to embed programs written in another programming language inside of a Haskell program. This enables writing parts of the program in the concrete, domain specific syntax of a different programming language. It has the benefit to think about -- and to express -- domain specific problems in the language best suited for the task. In particular, it lets a user focus on the domain specific problem and removes all additional language burdens induced by inconvenient syntax, unsuited control constructs, etc. Programs from the embedded language are parsed and translated into corresponding (but syntactically heavier) Haskell code at compile-time by Template Haskell. In this sense, (e.g.,) the shakespearean template languages from the <code>shakespeare</code> library use Template Haskell at their core. They expose succinct domain specific languages to write HTML, CSS, and Javascript code inside of a Haskell based web application.<br />
<br />
= Template Haskell by Examples =<br />
<br />
In this section, we will review the Template Haskell features to write meta programs. The first set of examples show-cases Template Haskell's potential as a code generator; the second set of examples highlights its facilities to create embedded domain specific languages (EDSLs). All examples require GHC's language extension <code>TemplateHaskell</code> to be enabled.<br />
<br />
To avoid confusion in the sequel, we distinguish between meta programs and object programs. Meta programs are the Haskell programs that run at compile-time and which generate Template Haskell object programs as the results of their execution; they are the programs that devise or manipulate other programs by some algorithmic means. Object programs, on the other hand, are the Template Haskell programs manipulated and built by the Haskell meta programs at compile-time.<br />
<br />
== Template Haskell as a Code Generator ==<br />
<br />
As an introductory example, consider Haskell's <code>Prelude</code> function <hask>curry :: ((a,b) -> c) -> a -> b -> c</hask>, which converts a function taking a pair to its curried equivalent. Unfortunately, there are no <code>Prelude</code> functions that provide the same currying functionality for functions taking arbitrary <math>n</math>-tuples. Moreover, having to write more than a few of these functions manually is, while trivial, a very repetitive and cumbersome task. Instead we wish to generate needed <hask>curry3</hask>, <hask>curry5</hask>, or <hask>curry8</hask> functions through a single meta program on demand. Template Haskell lets us do just this. The idea is to write a meta function <hask>curryN :: Int -> Q Exp</hask> which, given a number <code>n >= 1</code>, constructs the ''source code'' for an <math>n</math>-ary <hask>curry</hask> function:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import Control.Monad<br />
import Language.Haskell.TH<br />
<br />
curryN :: Int -> Q Exp<br />
curryN n = do<br />
f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
let args = map VarP (f:xs)<br />
ntup = TupE (map VarE xs)<br />
return $ LamE args (AppE (VarE f) ntup)<br />
</haskell><br />
<br />
For input <math>n</math>, meta function <hask>curryN</hask> builds a lambda abstraction <hask>LamE</hask> that pattern matches against a function <hask>f</hask> and <math>n</math> argument variables <hask>x1</hask>, <hask>x2</hask>, ..., <hask>xn</hask>; in its body, it then applies function <hask>f</hask> to the <math>n</math>-tuple <hask>(x1, x2, ..., xn)</hask> derived from the pattern matched variables. The names used to refer to the variables <hask>f</hask> and <hask>x1</hask> through <hask>xn</hask> are generated monadically by function <hask>newName :: String -> Q Name</hask> to always generate fresh names not used anywhere else. Hence, the value returned by <hask>curryN</hask> is a monadic computation of type <code>Q Exp</code>. When executed, this monadic computation yields an expression <code>Exp</code> representing the object program of an <math>n</math>-ary curry function. For example, <hask>(curryN 3)</hask> returns a monadic computation that yields an expression representing a <hask>curry3</hask> function of type <hask>((a, b, c) -> d) -> a -> b -> c -> d</hask> in abstract syntax.<ref>Note that meta function <hask>curryN</hask> cannot be written in normal Haskell per se as the type for a generated <math>n</math>-ary curry function depends on <math>n</math>. Thus, the definition of <hask>curryN</hask> requires ''dependent types'' to be expressed in Haskell, a feature not yet present. However, there already exist ingenious alternatives to "faking" dependent types in Haskell; see for instance [http://www.brics.dk/RS/01/10/ this paper] for a solution to simulate functions like <hask>curryN</hask> without dependent types).</ref><br />
<br />
<br />
To run a meta program like <hask>curryN</hask> at compile-time, we enclose it with Template Haskell's ''splice'' operator <code>$</code> by writing (e.g.,) <hask>$(curryN 3)</hask>. This evaluates the meta program <code>curryN 3</code> and puts the resulting object program <hask>\f x1 x2 x3 -> f (x1, x2, x3)</hask> in place of the splice. In general, the splice operator <code>$</code> can be applied to any monadic <code>Q</code> computation, hereby performing this computation at compile-time and inserting the resulting object program as real Haskell code. To ensure type safety, meta programs to be run are type checked beforehand to indeed yield a valid Template Haskell object program. Hence, only imported, fully-typechecked meta programs can be run via the splice operator <code>$</code>: in particular, we have to evaluate the meta program <code>$(curryN 3)</code> in a separate module to where <code>curryN</code> is defined.<br />
<br />
To generate function declarations for the first <math>n</math> curry functions, we can devise a further meta program on top of <hask>curryN</hask> as follows:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
Running <hask>$(genCurries 20)</hask> will then splice in the first 20 curry functions at compile-time, namely:<br />
<br />
<haskell><br />
curry1 = \ f x1 -> f (x1)<br />
curry2 = \ f x1 x2 -> f (x1, x2)<br />
curry3 = \ f x1 x2 x3 -> f (x1, x2, x3)<br />
curry4 = \ f x1 x2 x3 x4 -> f (x1, x2, x3, x4)<br />
...<br />
curry20 = \ f x1 x2 ... x20 -> f (x1, x2, ..., x20)<br />
</haskell><br />
<br />
Note that in this case, <hask>genCurries</hask> returns a list of top-level function declarations that bind the anonymous lambda abstractions built by <hask>curryN</hask>. Also, to name the function bindings, we use function <hask>mkName :: String -> Name</hask> instead of <hask>newName :: String -> Q Name</hask>. The reason is that here we want to generate functions <hask>curry1</hask> to <hask>curry20</hask> with exactly the prescribed names, so they can be captured and referred to from other parts of the program.<br />
<br />
Evaluating Haskell (meta) programs at compile-time and splicing in the generated object programs as regular Haskell code is the first central building block of Template Haskell. The two other core mechanisms are exhibited by the implementations of <hask>curryN</hask> and <hask>genCurries</hask>: algebraic data types and the quotation monad <code>Q</code>.<br />
<br />
First, object programs created by Template Haskell are represented as regular algebraic data types, describing a program in the form of an abstract syntax tree. The Template Haskell library provides algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> to represent Haskell's surface syntax of expressions, patterns, declarations, and types, respectively. Virtually every concrete Haskell syntactic construct has a corresponding abstract syntax constructor in one of the four ADTs. Furthermore, all Haskell identifiers are represented by the abstract <code>Name</code> data type. By representing object programs as regular algebraic data types (and thus as data), normal Haskell can be used as the meta programming language to build object programs.<br />
<br />
Second, TH object programs are built inside the quotation monad <code>Q</code>. This monad is performed by the splice operator "<code>$</code>" at compile-time as part of evaluating the meta program. In the examples so far, the <code>Q</code> monad was only needed to provide fresh identifiers with function <hask>newName :: String -> Q Name</hask> for the generated Haskell expressions. The other main feature that requires a monadic construction of object programs is ''reification'', which allows to query compile-time information during the object program's construction. We will explain reification in detail later.<br />
<br />
Thus, Template Haskell's core functionality constitutes evaluating object programs with "<code>$</code>" and building them from algebraic data types inside the quotation monad <code>Q</code>. However, constructing object programs in terms of their abstract syntax trees is quite verbose and leads to clumsy meta programs. Therefore the Template Haskell API also provides two further interfaces to build object programs more conveniently: ''syntax construction functions'' and ''quotation brackets''.<br />
<br />
Syntax construction functions directly relate to the syntax constructors from the algebraic data types <code>Exp</code>, <code>Pat</code>, <code>Dec</code>, and <code>Type</code> for representing Haskell code. However, they hide the monadic nature of building object programs. For example, recall our definition of the <hask>genCurries</hask> meta function from above:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = do<br />
cury <- curryN ith<br />
let name = mkName $ "curry" ++ show ith<br />
return $ FunD name [Clause [] (NormalB cury) []]<br />
</haskell><br />
<br />
To use the object program generated by the sub call to <hask>curryN</hask> in the larger context of the returned function declaration, we have to first perform <hask>curryN</hask> and bind its result to <hask>cury</hask>. The reason is that we have to account for <hask>curryN</hask>'s generation of fresh names before we can continue. Using syntax construction functions instead of data constructors, however, abstracts from the monadic construction of <hask>genCurries</hask>, thus making its code a little shorter:<br />
<br />
<haskell><br />
genCurries :: Int -> Q [Dec]<br />
genCurries n = forM [1..n] mkCurryDec<br />
where mkCurryDec ith = funD name [clause [] (normalB (curryN ith)) []]<br />
where name = mkName $ "curry" ++ show ith<br />
</haskell><br />
<br />
The new <code>funD</code>, <code>clause</code>, and <code>normalB</code> functions directly correspond to the formerly used <code>FunD</code>, <code>Clause</code>, and <code>NormalB</code> constructors. The only difference lies in their types:<br />
<br />
{|<br />
|-<br />
|<hask>FunD :: Name -> [Clause] -> Dec</hask><br />
|<hask>funD :: Name -> [Q Clause] -> Q Dec</hask><br />
|-<br />
|<hask>Clause :: [Pat] -> Body -> Clause</hask><br />
|<hask>clause :: [Q Pat] -> Q Body -> Q Clause</hask><br />
|-<br />
|<hask>NormalB :: Exp -> Body</hask><br />
|<hask>normalB :: Q Exp -> Q Body</hask><br />
|}<br />
<br />
While the syntax constructors work with raw TH expressions, the syntax construction functions expect their monadic counterparts. They construct a TH object program directly in <code>Q</code>, thus freeing the API consumer from doing the monadic wrapping and unwrapping manually. For every syntax constructor, there is a corresponding monadic syntax construction function provided.<br />
<br />
On top of syntax construction functions, quotation brackets are a further shortcut for representing Haskell code. They allow to specify an object program using just regular Haskell syntax by enclosing it inside oxford brackets <code>[| .. |]</code>. That way, object programs can be specified yet much more succinctly. For example, a meta program building a Haskell expression for the identity function is still quite verbose, if expressed with either ADTs or syntax construction functions:<br />
<br />
<haskell><br />
genId :: Q Exp<br />
genId = do<br />
x <- newName "x"<br />
lamE [varP x] (varE x)<br />
</haskell><br />
<br />
Using quotation brackets, writing the same meta program can be abbreviated much further as:<br />
<br />
<haskell><br />
genId' :: Q Exp<br />
genId' = [| \x -> x |]<br />
</haskell><br />
<br />
Quotation brackets quote regular Haskell code as the corresponding object program fragments inside the <code>Q</code> monad. There are quotation brackets for quoting Haskell expressions (<code>[e| .. |]|</code>), patterns (<code>[p| .. |]</code>), declarations (<code>[d| .. |]</code>), and types (<code>[t| .. |]</code>). Writing <code>[| .. |]</code> is hereby just another way of saying <code>[e| .. |]</code>. Using quotation brackets in a sense ''lifts'' Haskell's concrete syntax into corresponding object program expressions inside the <code>Q</code> monad. By doing so, quotation brackets represent the dual of the already introduced splice operator <code>$</code>: Evaluating a meta program with "<code>$</code>" splices in the generated object program as real Haskell code; in contrast, quotation brackets <code>[| .. |]</code> turn real Haskell code into an object program. Consequently, quotation brackets and the splice operator cancel each other out. The equation <code>$([| e |]) = e</code> holds for all expressions <code>e</code> and similar equations hold for declarations, and types<ref name="th2" />.<br />
<br />
In addition, there is support for quoting Haskell (value and type) identifiers as corresponding <code>Name</code>s inside Template Haskell. This allows to refer to regular Haskell identifiers from within TH object programs. For example, writing <hask>'genId</hask> yields a TH <code>Name</code> referring to the <hask>genId</hask> identifier. Similarly, <hask>''Q</hask> gives a <code>Name</code> referring to the <code>Q</code> type identifier.<br />
<br />
=== Generic Maps ===<br />
<br />
As a second example that uses both syntax construction functions as well as quotation brackets, let's consider a meta program <hask>mapN :: Int -> Q Dec</hask> to build "generic" <hask>map</hask> functions at compile-time. Invoking <hask>$(mapN 1)</hask> should generate the well-known standard function <hask>map :: (a -> b) -> [a] -> [b]</hask>; evaluating <hask>$(mapN 2)</hask> should splice in a binary map function of type <hask>(a -> b -> c) -> [a] -> [b] -> [c]</hask>, and so on.<ref>Note that <math>n</math>-ary maps are better written using Applicative Functors and <code>ZipList</code>s, as this allows to define them first-class from within regular Haskell. For understanding Template Haskell as a code generator, this example is still useful though.</ref><br />
<br />
<haskell><br />
mapN :: Int -> Q Dec<br />
mapN n<br />
| n >= 1 = funD name [cl1, cl2]<br />
| otherwise = fail "mapN: argument n may not be <= 0."<br />
where<br />
name = mkName $ "map" ++ show n<br />
cl1 = do f <- newName "f"<br />
xs <- replicateM n (newName "x")<br />
ys <- replicateM n (newName "ys")<br />
let argPatts = varP f : consPatts<br />
consPatts = [ [p| $(varP x) : $(varP ys) |]<br />
| (x,ys) <- xs `zip` ys ]<br />
apply = foldl (\ g x -> [| $g $(varE x) |])<br />
first = apply (varE f) xs<br />
rest = apply (varE name) (f:ys)<br />
clause argPatts (normalB [| $first : $rest |]) []<br />
cl2 = clause (replicate (n+1) wildP) (normalB (conE `[])) []<br />
</haskell><br />
<br />
The implementation of <hask>mapN</hask> is very much in the spirit of meta function <hask>curryN</hask> from the first example. For instance, evaluating splice <hask>$(mapN 3)</hask> splices in the following map function at compile-time:<br />
<br />
<haskell><br />
map3 f (x:xs) (y:ys) (z:zs) = f x y z : map3 f xs ys zs<br />
map3 _ _ _ _ = []<br />
</haskell><br />
<br />
Nonetheless, meta function <hask>mapN</hask> exhibits a couple of new Template Haskell features: First, quotation brackets and splices are used in several places to abbreviate the object program construction. For example, helper definition <hask>apply</hask> used to generate <hask>map3</hask>'s body <hask>f x y z : map3 f xs ys zs</hask> shows the use of quotation brackets; it also highlights how splicing (<hask>$</hask>) and quotes (<hask>[| .. |]</hask>) cancel each other out. Second, identifier quotes (namely, <hask>'[]</hask>) are used to create an object program <code>Name</code> that refers to Haskell's built-in list constructor <hask>[]</hask>. Third, the example advertises how all three APIs for building Template Haskell object programs can be interleaved. The lowermost verbose API of building a raw TH data value inside the quotation monad <code>Q</code> can be abbreviated, where possible, with syntax constructor functions and quotation brackets.<br />
<br />
Lastly, the <hask>mapN</hask> example exemplifies how Haskell's static scoping is extended to object programs. The scoping principle for object programs is just as in normal Haskell: Identifiers are bound to their lexically enclosing binders in scope at the point the object program is ''defined''. Quotation brackets and splices don't alter static scopes, even though splices may bring an object program into scope at a location, where a conflicting closure is present. For example, consider this snippet:<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
static :: Q Exp<br />
static = [| x |]<br />
<br />
plus42 :: Int -> Int<br />
plus42 x = $static + x<br />
</haskell><br />
<br />
Here the occurrence of <hask>x</hask> in <hask>static</hask> refers to the global identifier <hask>x</hask> that is lexically in scope during its definition. Splicing in <hask>static</hask> into a different scope later where a different local <hask>x</hask> is present (i.e., <hask>plus42</hask>'s local identifier <hask>x</hask>), doesn't alter the link between <hask>static</hask>'s <hask>x</hask> and the global identifier <hask>x</hask>.<br />
<br />
The only exception to static scoping in Template Haskell are the names generated by <hask>mkName :: String -> Name</hask>. These names implement dynamic scoping and ''can'' be captured in spliced-in code. Changing the previous snippet to<br />
<br />
<haskell><br />
x :: Int<br />
x = 42<br />
<br />
dynamic :: Q Exp<br />
dynamic = VarE (mkName "x")<br />
<br />
times2 :: Int -> Int<br />
times2 x = $dynamic + x<br />
</haskell><br />
<br />
results in the identifier <hask>x</hask> spliced in by <hask>$dynamic</hask> to be bound to the closest <hask>x</hask> in scope. Hence, its binder is <hask>times2</hask>'s local identifier <hask>x</hask> and ''not'' the global <hask>x</hask>.<br />
<br />
=== Reification ===<br />
<br />
The final major Template Haskell feature not yet described is program ''reification''. Briefly, reification allows a meta program to query compile-time information about other program parts while constructing the object program. It allows the meta program to inspect other program pieces to answer questions such as: "what's this variable's type?", "what are the class instances of this type class?", or "which constructors does this data type have and and how do they look like?". The main use case is to generate boilerplate code which ''auto-completes'' manually written code. A prime example is to generically derive type class instances from bare data type definitions.<br />
<br />
Suppose we've defined the following polymorphic data types for representing potentially erroneous values, lists, and binary trees, respectively:<br />
<br />
<haskell><br />
data Result e a = Err e | Ok a<br />
data List a = Nil | Cons a (List a)<br />
data Tree a = Leaf a | Node (Tree a) a (Tree a)<br />
</haskell><br />
<br />
Moreover, suppose we want to derive <code>Functor</code> instances for all of these types. Deriving these instances manually is straightforward, but writing them all out by hand is quite cumbersome. Especially since writing a <code>Functor</code> instance follows the same pattern across all of the above types and in fact any type <code>T a</code>.<br />
<br />
To make a type constructor <code>T</code> an instance of <code>Functor</code>, one needs to implement method <hask>fmap :: (a -> b) -> T a -> T b</hask>. Its definition is hereby precisely determined by parametricity and the functor laws: By parametricity, all values of type <code>a</code> must be replaced according to the provided function with values of type <code>b</code>. Furthermore, by the functor laws, all other shapes of the input value of type <code>T a</code> must be preserved when transforming it to the output value of type <code>T b</code>.<br />
<br />
Meta function <hask>deriveFunctor :: Name -> Q [Dec]</hask> below implements the idea of this algorithm:<br />
<br />
<haskell><br />
data Deriving = Deriving { tyCon :: Name, tyVar :: Name }<br />
<br />
deriveFunctor :: Name -> Q [Dec]<br />
deriveFunctor ty<br />
= do (TyConI tyCon) <- reify ty<br />
(tyConName, tyVars, cs) <- case tyCon of<br />
DataD _ nm tyVars cs _ -> return (nm, tyVars, cs)<br />
NewtypeD _ nm tyVars c _ -> return (nm, tyVars, [c])<br />
_ -> fail "deriveFunctor: tyCon may not be a type synonym."<br />
<br />
let (KindedTV tyVar StarT) = last tyVars<br />
instanceType = conT ``Functor `appT`<br />
(foldl apply (conT tyConName) (init tyVars))<br />
<br />
putQ $ Deriving tyConName tyVar<br />
sequence [instanceD (return []) instanceType [genFmap cs]]<br />
where<br />
apply t (PlainTV name) = appT t (varT name)<br />
apply t (KindedTV name _) = appT t (varT name)<br />
</haskell><br />
<br />
Given the name of a type constructor (e.g. <code>Result</code>, <code>List</code>, etc.), <hask>deriveFunctor</hask> derives the code for this type constructor's <code>Functor</code> instance. For example, running the splice <hask>$(deriveFunctor ''Tree)</hask> generates the following code:<br />
<br />
<haskell><br />
instance Functor Tree where<br />
fmap f (Leaf x) = Leaf (f x)<br />
fmap f (Node l x r) = Node (fmap f l) (f x) (fmap f r)<br />
</haskell><br />
<br />
Meta function <hask>deriveFunctor</hask> shows reification in action. It calls function <hask>reify :: Name -> Q Info</hask> on the input type constructor's name to yield information about this data type's definition. Using <hask>reify</hask>, it thus learns whether the data type was defined using the <code>data</code> or <code>newtype</code> keyword, which constructors it defines and what their shapes are. Based on the learned structure, <hask>deriveFunctor</hask> is then able to generate a suitable definition of <hask>fmap</hask> and its different clauses via the auxiliaries <hask>genFmap</hask>, <hask>genFmapClause</hask>, and <hask>newField</hask>, defined below. These auxiliary definitions generate one <hask>fmap</hask> clause for each of the data type's constructors. And each clause then transforms its constructor by recursively modifying all of the constructor's fields of type <code>a</code> through <hask>fmap</hask>'s function <code>f</code>, while retaining all other shapes.<br />
<br />
<haskell><br />
genFmap :: [Con] -> Q Dec<br />
genFmap cs<br />
= do funD `fmap (map genFmapClause cs)<br />
<br />
genFmapClause :: Con -> Q Clause<br />
genFmapClause c@(NormalC name fieldTypes)<br />
= do f <- newName "f"<br />
fieldNames <- replicateM (length fieldTypes) (newName "x")<br />
<br />
let pats = varP f:[conP name (map varP fieldNames)]<br />
body = normalB $ appsE $<br />
conE name : map (newField f) (zip fieldNames fieldTypes)<br />
<br />
clause pats body []<br />
<br />
newField :: Name -> (Name, StrictType) -> Q Exp<br />
newField f (x, (_, fieldType))<br />
= do Just (Deriving typeCon typeVar) <- getQ<br />
case fieldType of<br />
VarT typeVar' | typeVar' == typeVar -><br />
[| $(varE f) $(varE x) |]<br />
ty `AppT` VarT typeVar' |<br />
leftmost ty == (ConT typeCon) && typeVar' == typeVar -><br />
[| fmap $(varE f) $(varE x) |]<br />
_ -> [| $(varE x) |]<br />
<br />
leftmost :: Type -> Type<br />
leftmost (AppT ty1 _) = leftmost ty1<br />
leftmost ty = ty<br />
</haskell><br />
<br />
In more detail, <hask>deriveFunctor</hask> works as follows. First, via <hask>reify</hask> it observes the input data type's name <hask>tyConName</hask>, its declared type variables <hask>tyVars</hask>, and its exposed constructors <hask>cs</hask>. It then determines the data type's right-most type variable <hask>tyVar</hask> and stores it together with the data type's type constructor name <hask>tyConName</hask> in the <hask>Q</hask> monad's user state. This state information is retrieved later again from inside auxiliary definition <hask>newField</hask>. Next, <hask>deriveFunctor</hask> derives a <hask>Functor</hask>'s <hask>fmap</hask> definition using auxiliary <hask>genFmap</hask>. For each of the input data type's value constructors <hask>cs</hask>, <hask>genFmap</hask> generates an <hask>fmap</hask> clause using helper function <hask>genFmapClause</hask>. The latter recursively maps the provided function <hask>f :: a -> b</hask> over all of a constructor's fields of type <code>a</code>, while leaving all other fields untouched. Each field is hereby modified through <hask>f</hask> or left unchanged by auxiliary <hask>newField</hask> based on the field's type: if a field's type is <code>a</code> (which is stored in the retrieved <hask>tyVar</hask> inside function <hask>newField</hask>), then <hask>f</hask> needs to be applied to it; otherwise it needs to remain unchanged.<br />
<br />
<br />
In an analogous manner to <hask>deriveFunctor</hask>, a function <hask>deriveFoldable :: Name -> Q [Dec]</hask> can be devised to derive a data type's <code>Foldable</code> instance. All that is needed is to provide a definition for function <hask>foldMap :: Monoid m => (a -> m) -> T a -> m</hask>. Again, <hask>foldMap</hask>'s definition follows directly from a data type's bare definition, which can be observed by means of reification. This highlights particularly how the functionality offered by Template Haskell provides a low-level API into the GHC compiler to manipulate abstract syntax trees at compile-time. This mechanism is quite powerful and even allows to simulate some of GHC's offered language extensions, e.g., <code>-XDeriveFunctor</code> and <code>-XDeriveFoldable</code>, to be implemented as a library on top of Template Haskell.<br />
<br />
== Template Haskell for building Embedded Domain specific Languages (EDSLs) ==<br />
<br />
To see Template Haskell's potential for building an EDSL, consider the problem of pattern matching text with regular expressions. Suppose, as part of a Haskell program we need to devise many different regular expressions and use them to pattern match text fragments. Regular expressions are easily defined by an algebraic data type capturing their structure, as well as an evaluator checking whether a regular expression matches some input string. <ref>This example draws on Penn's CIS 552 ''Advanced Programming'' course, specifically Assignment 5: http://www.seas.upenn.edu/~cis552/current/hw/hw05/Main.html.</ref><br />
<br />
<haskell><br />
data RegExp<br />
= Char (Set Char) -- [a], [abc], [a-z]; matches a single character from the specified class<br />
| Alt RegExp RegExp -- r1 | r2 (alternation); matches either r1 or r2<br />
| Seq RegExp RegExp -- r1 r2 (concatenation); matches r1 followed by r2<br />
| Star RegExp -- r* (Kleene star); matches r zero or more times<br />
| Empty -- matches only the empty string<br />
| Void -- matches nothing (always fails)<br />
| Var String -- a variable holding another regexp (explained later)<br />
deriving Show<br />
<br />
match :: RegExp -> String -> Bool<br />
match r s = nullable (foldl deriv r s)<br />
</haskell><br />
<br />
The evaluator <hask>match</hask> is hereby based on the concept of derivatives<ref name="regexp-derivs" />: an initial regular expression <hask>r</hask> matches an input string <hask>s</hask>, if <hask>r</hask> matches the first character of <hask>s</hask> and its derivative regular expression <hask>(deriv r)</hask> matches the remainder of <hask>s</hask>:<br />
<br />
<haskell><br />
nullable :: RegExp -> Bool<br />
nullable (Char _) = False<br />
nullable (Alt r1 r2) = nullable r1 || nullable r2<br />
nullable (Seq r1 r2) = nullable r1 && nullable r2<br />
nullable (Star _) = True<br />
nullable Empty = True<br />
nullable Void = False<br />
nullable (Var _) = False<br />
<br />
deriv :: RegExp -> Char -> RegExp<br />
deriv (Char cs) c<br />
| c `Set.member` cs = Empty<br />
| otherwise = Void<br />
deriv (Alt r1 r2) c = Alt (deriv r1 c) (deriv r2 c)<br />
deriv (Seq r1 r2) c<br />
| nullable r1 = Alt (Seq (deriv r1 c) r2) (deriv r2 c)<br />
| otherwise = Seq (deriv r1 c) r2<br />
deriv (Star r) c = deriv (Alt Empty (Seq r (Star r))) c<br />
deriv Empty _ = Void<br />
deriv Void _ = Void<br />
deriv (Var _) _ = Void<br />
</haskell><br />
<br />
The <code>RegExp</code> data type and the <hask>match</hask> function solve the initially posed problem of providing regular expressions in Haskell. However, specifying regular expressions in abstract syntax is extremely tedious. For example, consider defining a regular expression for checking the wellformedness of email addresses ending with the top level domain '''.com'''. In its usual concrete syntax, such a regular expression is easily defined as <code>([a-z]|[0-9])*@([a-z]|[0-9])*.com</code>, but writing it in terms of the <code>RegExp</code> dataype is verbose and unintuitive. Moreover, parsing functions like<br />
<br />
* <hask>compile :: String -> RegExp</hask>, or<br />
* <hask>compile' :: String -> Either CompileError RegExp</hask><br />
<br />
do not remedy the problem of working with regular expressions in concrete syntax. Due to "compiling" regular expressions at run time, they don't provide any compile-time type-safety guarantees that the input raw expression is wellformed; thus they lead to either run time exceptions for illformed regular expressions (e.g., <hask>compile</hask>) or induce a tedious handling for compiled regexes (e.g., <hask>compile'</hask>).<br />
<br />
To preserve type safety and yet to be able to use regular expressions conveniently, we want to embed the concrete regular expression syntax into the Haskell host language. This can be done via Template Haskell's quasi quotes and furthermore enabling the <code>QuasiQuotes</code> extension. This allows defining ''quasi quotes'' for regular expressions, denoted <code>[regex| .. |]</code>, where anything inside the quasi quote is considered part of an embedded regular expression language. Using quasi quotes, we can then specify the regex for email addresses from above naturally as follows:<br />
<br />
<haskell><br />
validDotComMail :: RegExp<br />
validDotComMail = [regex|([a-z]|[0-9])*@([a-z]|[0-9])*.com|]<br />
</haskell><br />
<br />
We can even compose regular expressions easily from smaller building blocks:<br />
<br />
<haskell><br />
alphaNum, validDotComMail' :: RegExp<br />
alphaNum = [regex|[a-z]|[0-9]|]<br />
validDotComMail' = [regex|${alphaNum}*@${alphaNum}*.com|]<br />
</haskell><br />
<br />
Writing <hask>${alphaNum}</hask> interpolates the regex referred to by <hask>alphaNum</hask> into the larger regex <hask>validDotComMail'</hask>. In essence, this means that we can define our own notion of splicing values from the Haskell meta language into the embedded object language of regular expressions. We can go further and even allow to run Haskell code when interpolating with <code>${..}</code>. For example, refining our wellformedness check for '''.com''' mail addresses, we might want to ensure at least one character to occur on either side of the "@" symbol:<br />
<br />
<haskell><br />
chars, validDotComMail'' :: RegExp<br />
chars = [regex|[a-z]|[A-Z]|[0-9]|[-_.]|]<br />
validDotComMail'' = [regex|${plus chars}@${plus chars}.com|]<br />
<br />
plus :: RegExp -> RegExp<br />
plus r = Seq r (Star r)<br />
</haskell><br />
<br />
Here, <hask>plus</hask> corresponds to the usual regex combinator that requires a given regex to occur at least once. Note how <hask>plus</hask> is defined as a regular Haskell function and then used ''inside'' of the embedded regex language to build the regular expression for <hask>validDotComMail''</hask>.<br />
<br />
Intuitively, a quasi quote like <code>[regex| .. |]</code> converts an embedded language's concrete syntax to Haskell code at compile-time. It is defined by a ''quasi quoter'', which is a parser for the embedded language. Its task is to parse the embedded language's syntax into a corresponding Template Haskell expression and then to splice this expression as real Haskell code in place of the quasi quote. The conversion of embedded language code to corresponding Haskell code hereby happens before typechecking the Haskell module. Hence, trying to splice in malformed embedded language fragments will raise a Haskell type error at compile-time.<br />
<br />
The quasi quoter <code>regex</code> for our embedded language of regular expressions can be defined as follows:<br />
<br />
<haskell><br />
regex :: QuasiQuoter<br />
regex = QuasiQuoter {<br />
quoteExp = compile<br />
, quotePat = notHandled "patterns"<br />
, quoteType = notHandled "types"<br />
, quoteDec = notHandled "declarations"<br />
}<br />
where notHandled things = error $<br />
things ++ " are not handled by the regex quasiquoter."<br />
<br />
compile :: String -> Q Exp<br />
compile s =<br />
case P.parse regexParser "" s of<br />
Left err -> fail (show err)<br />
Right regexp -> [e| regexp |]<br />
</haskell><br />
<br />
That is, formally a <code>QuasiQuoter</code> consists of four parsers,<br />
<br />
<haskell><br />
quoteExp :: String -> Q Exp<br />
quotePat :: String -> Q Pat<br />
quoteType :: String -> Q Type<br />
quoteDec :: String -> Q Dec<br />
</haskell><br />
<br />
to parse raw strings of the embedded language into the different categories of Haskell syntax. In this example, however, we only want to splice embedded regular expressions into the context of Haskell expressions, so we only define the <code>quoteExp</code> parser in the <code>regex</code> quasi quoter. This parser compiles an embedded regular expression given as a string into a corresponding Template Haskell expression.<br />
<br />
Compilation by the <hask>compile</hask> function proceeds in two stages: First, we parse the input string regex into a corresponding <code>RegExp</code> value. Second, we encode this <code>RegExp</code> value as a Haskell expression in Template Haskell's <code>Q Exp</code> type. It is the second step that allows us to interpolate variables (or even code) from the Haskell host language into the EDSL for regular expressions.<br />
<br />
Parsing a raw regular expression into a corresponding <code>RegExp</code> value is a routine task using (e.g.) the ''parsec'' library:<br />
<br />
<haskell><br />
regexParser :: Parsec String () RegExp<br />
regexParser = alts <* eof where<br />
atom = try var <|> char<br />
var = Var <$> (string "${" *> many1 (noneOf "}") <* P.char '}')<br />
char = charclass <|> singlechar<br />
singlechar = (Char . Set.singleton) <$> noneOf specials<br />
charclass = fmap (Char . Set.fromList) $<br />
P.char '[' *> content <* P.char ']'<br />
content = try (concat <$> many1 range)<br />
<|> many1 (noneOf specials)<br />
range = enumFromTo<br />
<$> (noneOf specials <* P.char '-')<br />
<*> noneOf specials<br />
alts = try (Alt <$> seqs <*> (P.char '|' *> alts)) <|> seqs<br />
seqs = try (Seq <$> star <*> seqs) <|> star<br />
star = try (Star <$> (atom <* P.char '*'))<br />
<|> try (Star <$> (P.char '(' *> alts <* string ")*"))<br />
<|> atom<br />
specials = "[]()*|"<br />
</haskell><br />
<br />
To represent regular expressions of type <code>RegExp</code> as Template Haskell expressions of type <code>Q Exp</code>, Template Haskell's <code>Lift</code> typeclass is used. Its method <hask>lift :: Lift a => a -> Q Exp</hask> lifts values from the Haskell meta language (e.g., a <code>RegExp</code> value) into Template Haskell's expression language (i.e., a <code>Q Exp</code> value). The <hask>lift</hask> function is implicitly invoked by quote <hask>[e| regexp |]</hask> in function <code>compile</code>.<br />
<br />
<br />
Most of the lifting is a direct encoding of the syntactic structure of the <code>RegExp</code> value; the only interesting case is when lifting the regular expression variable <hask>Var vars</hask>. In this case, we treat the words in the string <hask>vars</hask> as referring to identifiers from the Haskell host language, which we apply in a left associative manner to each other. Doing this enables interpolation of Haskell identifiers or even simple forms of Haskell expressions into our EDSL of regular expressions as shown by the regexes <hask>validDotComMail'</hask>, and <hask>validDotComMail''</hask> above.<br />
<br />
<haskell><br />
instance Lift a => Lift (Set a) where<br />
lift set = appE (varE `Set.fromList) (lift (Set.toList set))<br />
<br />
instance Lift RegExp where<br />
-- lift :: RegExp -> Q Exp<br />
lift (Char cs) = apply `Char [lift cs]<br />
lift (Alt r1 r2) = apply `Alt (map lift [r1, r2])<br />
lift (Seq r1 r2) = apply `Seq (map lift [r1, r2])<br />
lift (Star r1) = apply `Star (map lift [r1])<br />
lift Empty = apply `Empty []<br />
lift Void = apply `Void []<br />
lift (Var vars) = foldl1 appE $ map (varE . mkName) (words vars)<br />
<br />
apply :: Name -> [Q Exp] -> Q Exp<br />
apply n = foldl appE (conE n)<br />
</haskell><br />
<br />
These two steps constitute the conversion of raw string regular expressions into Template Haskell expressions inside of the <hask>compile</hask> function and define the <code>regex</code> quasiquoter. Whenever we write a quasi quote like <hask>[regex| .. |]</hask> in a Haskell expression context, <hask>regex</hask>'s parser <hask>quoteExp</hask> converts the regex EDSL into a Template Haskell expression <code>Q Exp</code> and splices in the result as a wellformed <code>RegExp</code> value. This example shows how Template Haskell and quasi quotes can be used to define a type-safe, domain specific language for regular expressions.<br />
<br />
=== Shakespearean Templates ===<br />
<br />
In much the same manner as in the last example, Template Haskell and quasi quotes are used in Michael Snoyman's <code>shakespeare</code> library<ref name="shakespeare" /><ref name="shakespeare-lib" />. It defines embedded templating languages for working with the internet's web languages from within a Haskell web application. In particular, the <code>shakespeare</code> library provides the template languages ''Hamlet'', ''Cassius'', and ''Julius'' for writing embedded HTML, CSS, and Javascript code, respectively. All three templating languages internally work quite similarly to the previous example's EDSL for regular expressions: quasi quotes allow one to write HTML, CSS, or JavaScript code in concrete (though slightly modified) syntax inside of Haskell. Moreover, identifiers from the Haskell host language as well as code fragments can be interpolated into the template languages at compile-time. In the remainder we will briefly show-case the <code>shakespeare</code> library's templating language Hamlet for creating HTML documents; the other templating languages Cassius and Julius are similar.<br />
<br />
To create and output a simple web page from inside a Haskell application, the following is enough:<br />
<br />
<haskell><br />
import Data.Text<br />
import Text.Hamlet<br />
import Text.Blaze.Html.Renderer.String<br />
<br />
data Page = Home | About | Github<br />
<br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls Github _ = "https://www.github.com/bollmann"<br />
<br />
webPage :: Text -> Text -> HtmlUrl Page<br />
webPage title content = [hamlet|<br />
<html><br />
<head><br />
<title>#{Text.toUpper title}<br />
<body><br />
<h1>#{title}<br />
<div>Welcome to my Shakespearean Templates page!<br />
<hr><br />
<div>Links:<br />
<ul><br />
<a href=@{Home}>My Homepage<br />
<a href=@{About}>About me<br />
<a href=@{Github}>Check out my Github<br />
<hr><br />
<div>#{content}<br />
|]<br />
<br />
main = putStrLn $ renderHtml $<br />
webPage "Hello Shakespeare!" "Hello World!" mkUrls<br />
</haskell><br />
<br />
Running this Haskell program, outputs an HTML page as specified by the Hamlet templating language, embedded through quasi quote <hask>[hamlet| .. |]</hask> in function <hask>webPage</hask>. Hamlet closely resembles real HTML syntax, but is even more terse: instead of a closing HTML tag, Hamlet uses indentation to indicate the span of the tag. Furthermore, Hamlet allows to interpolate code or identifiers from the Haskell host language when creating an HTML template. Interpolation of Haskell code into Hamlet is done by writing <code>#{ .. }</code>. In the above example, the HTML page's title and content are interpolated from Haskell identifiers. Note particularly how in the webpage's title we uppercase the interpolated title using Haskell's <hask>Text.toUpper</hask> function ''inside'' of the Hamlet language.<br />
<br />
In addition to this standard interpolation, Hamlet can also interpolate links by writing <code>@{..}</code>. These links are specified as values of the <hask>Page</hask> data type inside the template and the <hask>mkUrls</hask> render function translates them to real URLs later. Hamlet's URL interpolation has commonly be phrased as creating "type-safe URLs". One reason is that, just like with normal variable interpolation, all interpolated links have to exist and be type correct at compile-time; in this case, links must be values of the <code>Page</code> data type. Hence, as soon as a link's constructor shape is changed, the compiler statically forces us to update all references to this link as well. Furthermore, there is only one distinct place in the code to maintain or update a link's raw URL, thus minimizing the risk of dead URLs.<br />
<br />
For example, suppose we want to add more external links to our web page. We could model this fact by changing the <hask>Page</hask> data type to<br />
<br />
<haskell><br />
data Page = Home | About | External ExternalPage<br />
data ExternalPage = Github | Haskell | Reddit<br />
</haskell><br />
<br />
and, moreover, changing the <hask>mkUrls</hask> renderer function to account for the new links:<br />
<br />
<haskell><br />
mkUrls :: Page -> [(Text, Text)] -> Text<br />
mkUrls Home _ = "/home.html"<br />
mkUrls About _ = "/about.html"<br />
mkUrls (External page) _ = mkExternalUrls page<br />
<br />
mkExternalUrls :: ExternalPage -> Text<br />
mkExternalUrls Github = "https://www.github.com"<br />
mkExternalUrls Haskell = "http://www.haskell.org"<br />
mkExternalUrls Reddit = "http://www.reddit.com/r/haskell"<br />
</haskell><br />
<br />
Doing just these changes, will then cause a compile-time error in our <hask>webPage</hask> template, since we haven't updated the <hask>Github</hask> reference to our newly adjusted link structure. Hence, the compiler reminds (and in fact forces) us to update all locations in the code that used the old <hask>Github</hask> link to now use the new <hask>External Github</hask> (as well as optionally the <hask>External Haskell</hask>, etc.) links.<br />
<br />
Finally, Hamlet allows to use some control constructs like if conditionals, for loops, and let bindings to embed basic business logic into a webpage's template. Michael Snoyman gives a gentle (and much more in-depth) introduction to shakespearean templates and Yesod<ref name="shakespeare" /><ref name="yesod" />.<br />
<br />
= References =<br />
<br />
<references><br />
<ref name="th1">Tim Sheard and Simon Peyton Jones. Template Meta-Programming for Haskell. SIGPLAN Not., 37(12):60-75, December 2002. URL: https://www.microsoft.com/en-us/research/publication/template-meta-programming-for-haskell/?from=http://research.microsoft.com/~simonpj/papers/meta-haskell/ </ref><br />
<ref name="th2">Tim Sheard and Simon Peyton Jones. Notes on Template Haskell, Version 2. URL: https://www.haskell.org/ghc/docs/papers/th2.ps, 2003.</ref><br />
<ref name="th3">Simon Peyton Jones. Major Proposed Revision of Template Haskell. URL: https://ghc.haskell.org/trac/ghc/blog/Template%20Haskell%20Proposal, 2010</ref><br />
<ref name="qq">Geoffrey Mainland. Why it's nice to be quoted: Quasiquoting for Haskell. In ''Proceedings of the ACM SIGPLAN Workshop on Haskell'', Haskell '07, pages 73-82, New York, NY, USA, 2007. ACM</ref><br />
<ref name="regexp-derivs">Janusz A. Brzozowski. Derivatives of regular expressions. J. ACM, 11(4):481–494, October 1964.</ref><br />
<ref name="shakespeare">Michael Snoyman. Shakespearean Templates. URL: http://www.yesodweb.com/book/shakespearean-templates [Accessed: May 2016].</ref><br />
<ref name="shakespeare-lib">Michael Snoyman. The <code>shakespeare</code> Haskell library. URL: http://hackage.haskell.org/package/shakespeare [Accessed: May 2016].</ref><br />
<ref name="yesod">Michael Snoyman. Haskell and Yesod. URL: http://www.yesodweb.com/book-1.4 [Accessed: May 2016].</ref><br />
<ref name="dep-tys">Daniel Friedlender and Mia Indrika. Do we need Dependent Types? J. Funct. Program. 10(4):409-415, July 2000.</ref><br />
</references></div>Enoksrdhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=62517Template Haskell2018-06-20T01:35:59Z<p>Enoksrd: /* Generating records which are variations of existing records */ Improve the example by adding comments and leading with the example usage</p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|glasgow_exts|template-haskell|a Template Haskell section}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [https://www.haskell.org/ghc/docs/papers/th2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [Name]<br />
as = [ mkName $ "a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ mkName $ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses [[Scrap your boilerplate]] (SYB) to address some of the pain of dealing with the rather large data types. We define <tt>mkOptional</tt> so that given a data type <tt><datatype></tt> it generates a new data type <tt><datatype>_opt</tt> that is like <tt><datatype></tt>, but where each record field <tt><field> :: <type></tt> is changed to <tt><field>_opt :: Maybe <type></tt>, and all types <tt><type></tt> that are defined in the same module <tt><datatype></tt> are replaced with <tt><type>_opt</tt>.<br />
<br />
First an example of using <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
<br />
data Foo = Foo { a :: Double<br />
, f :: Int }<br />
data Bar = Bar { x :: Foo<br />
, y :: String }<br />
<br />
mapM mkOptional [''Foo, ''Bar]<br />
</haskell><br />
<br />
The above generates the following new types <tt>Foo_opt</tt> and <tt>Bar_opt</tt>:<br />
<haskell><br />
data Foo_opt = Foo_opt { a_opt :: Maybe Double<br />
, f_opt :: Maybe Int }<br />
data Bar_opt = Bar_opt { x_opt :: Maybe Foo_opt<br />
, y_opt :: Maybe String }<br />
</haskell><br />
Note that <tt>x_opt</tt> has type <tt>Maybe Foo_opt</tt>, and not type <tt>Maybe Foo</tt>.<br />
<br />
Here is the implementation of <tt>mkOptional</tt>:<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybesAndOpts :: Maybe String -> Dec -> Q Dec<br />
addMaybesAndOpts modName dec =<br />
-- Apply @rename@ and @addMaybe@ everywhere in the<br />
-- declaration @dec@.<br />
--<br />
-- The SYB, @everywhere (mkT (f :: a -> a)) (x :: b)@<br />
-- applies @f@ to all data of type @a@ in @x@, and<br />
-- @everywhereM (mkM (f :: a -> m a) (x :: b)@ is<br />
-- similar, but applies @f@ everywhere in @x@ monadically.<br />
everywhere (mkT rename) <$><br />
everywhereM (mkM addMaybe) dec<br />
where<br />
-- Add the "_opt" suffix to a name, if it's from<br />
-- the given module.<br />
rename :: Name -> Name<br />
rename n = if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
-- Wrap the type of a record field in @Maybe@.<br />
addMaybe :: (Name, Strict, Type) -> Q (Name, Strict, Type)<br />
addMaybe (n, s, ty) = do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI dec <- reify n<br />
addMaybesAndOpts (nameModule n) dec<br />
</haskell><br />
<br />
<br />
[[Category:Language extensions]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=62515Template Haskell2018-06-18T23:43:46Z<p>Enoksrd: /* Select from a tuple */ Fix bugs in example code: Strings need to be converted to Names.</p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|glasgow_exts|template-haskell|a Template Haskell section}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [https://www.haskell.org/ghc/docs/papers/th2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [Name]<br />
as = [ mkName $ "a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ mkName $ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses syb to address some of the pain of dealing with the rather large data types. <br />
<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybes modName input = let<br />
<br />
rename :: GenericT<br />
rename = mkT $ \n -> if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
addMaybe :: GenericM Q<br />
addMaybe = mkM $ \(n :: Name, s :: Strict, ty :: Type) -> do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
in everywhere rename `fmap` everywhereM addMaybe input<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI d <- reify n<br />
addMaybes (nameModule n) d<br />
</haskell><br />
<br />
mkOptional then generates a new data type with all Names in that module with an added suffix _opt. Here is an example of its use:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
data Foo = Foo { a,b,c,d,e :: Double, f :: Int }<br />
<br />
mapM mkOptional [''Foo]<br />
</haskell><br />
<br />
Generates something like<br />
<haskell><br />
data Foo_opt = Foo_opt {a_opt :: Maybe Double, ..... f_opt :: Maybe Int}<br />
</haskell><br />
<br />
<br />
<br />
[[Category:Language extensions]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Template_Haskell&diff=62514Template Haskell2018-06-18T23:21:32Z<p>Enoksrd: Fix Template Haskell notes link</p>
<hr />
<div>'''[http://hackage.haskell.org/package/template-haskell Template Haskell]''' is a [[GHC]] extension to Haskell that adds compile-time metaprogramming facilities. The original design can be found here: http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/. It is [http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html included] in GHC since version 6. <br />
<br />
{{GHCUsersGuide|glasgow_exts|template-haskell|a Template Haskell section}}<br />
<br />
This page hopes to be a more central and organized repository of TH related things.<br />
<br />
<br />
=What is Template Haskell?=<br />
<br />
Template Haskell is an extension to Haskell 98 that allows you to do type-safe compile-time meta-programming, with Haskell both as the manipulating language and the language being manipulated. <br />
<br />
Intuitively Template Haskell provides new language features that allow us to convert back and forth between concrete syntax, i.e. what you would type when you write normal Haskell code, and abstract syntax trees. These abstract syntax trees are represented using Haskell datatypes and, at compile time, they can be manipulated by Haskell code. This allows you to reify (convert from concrete syntax to an abstract syntax tree) some code, transform it and splice it back in (convert back again), or even to produce completely new code and splice that in, while the compiler is compiling your module. <br />
<br />
For email about Template Haskell, use the [http://www.haskell.org/mailman/listinfo/glasgow-haskell-users GHC users mailing list]. It's worth joining if you start to use TH.<br />
<br />
<br />
= Template Haskell specification =<br />
<br />
Template Haskell is only documented rather informally at the moment. Here are the main resources:<br />
<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell The user manual section on Template Haskell]<br />
* [https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell-quasi-quotation The user manual section on quasi-quotation], which is closely related to Template Haskell.<br />
* [http://research.microsoft.com/~simonpj/papers/meta-haskell/ The original Template Haskell paper]<br />
* [https://www.haskell.org/ghc/docs/papers/th2.ps Notes on Template Haskell version 2], which describes changes since the original paper. Section 8 describes the difficulty with pattern splices, which are therefore not implemented.<br />
* [http://hackage.haskell.org/package/template-haskell The Template Haskell API]<br />
<br />
= Template Haskell tutorials and papers =<br />
<br />
* Bulat's tutorials:<br />
*# [http://web.archive.org/web/20100703060856/http://www.haskell.org/bz/thdoc.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TM2MxZjJjZjctMTQ0OS00YzcwLWE5N2QtMDI0YzE4NGUwZDM3 Google Docs]<br />
*# [http://web.archive.org/web/20100703060841/http://www.haskell.org/bz/th3.htm Wayback Machine], [http://docs.google.com/uc?id=0B4BgTwf_ng_TOGJkZjM4ZTUtNGY5My00ZThhLTllNDQtYzJjMWJiMzJhZjNj Google Docs]<br />
<br />
: One reader said "These docs are *brilliant* ! Exactly what I need to get an understanding of TH."<br />
<br />
<small>(Note: These documents are from [http://www.archive.org the Wayback machine] because the originals disappeared. They're public documents on Google docs, which shouldn't require logging in. However, if you're asked to sign in to view them, you're running into a known Google bug. You can fix it by browsing to [http://www.google.com Google], presumably gaining a cookie in the process.)</small><br />
<br />
* Dominik's [[A practical Template Haskell Tutorial| example-driven, practical introduction to Template Haskell]].<br />
<br />
<!--<br />
* Mark Snyder's Template Haskell chapter on the Software Generation and Configuration Report<br />
** http://nix.cs.uu.nl/dist/courses/sgc-report-unstable-latest/manual/chunk-chapter/templatehaskell.html<br />
--><br />
* A very short tutorial to understand the basics in 10 Minutes.<br />
** http://www.hyperedsoftware.com/blog/entries/first-stab-th.html<br />
<br />
* GHC Template Haskell documentation<br />
** https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#template-haskell<br />
<br />
* Papers about Template Haskell<br />
<br />
** Template metaprogramming for Haskell, by Tim Sheard and Simon Peyton Jones, Oct 2002. [[http://www.haskell.org/wikiupload/c/ca/Meta-haskell.ps ps]]<br />
** Template Haskell: A Report From The Field, by Ian Lynagh, May 2003. [[http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps ps]]<br />
** Unrolling and Simplifying Expressions with Template Haskell, by Ian Lynagh, December 2002. [[http://www.haskell.org/wikiupload/e/ed/Template-Haskell-Utils.ps ps]]<br />
** Automatic skeletons in Template Haskell, by Kevin Hammond, Jost Berthold and Rita Loogen, June 2003. [[http://www.haskell.org/wikiupload/6/69/AutoSkelPPL03.pdf pdf]]<br />
** Optimising Embedded DSLs using Template Haskell, by Sean Seefried, Manuel Chakravarty, Gabriele Keller, March 2004. [[http://www.haskell.org/wikiupload/b/b5/Seefried04th-pan.pdf pdf]]<br />
** Typing Template Haskell: Soft Types, by Ian Lynagh, August 2004. [[http://www.haskell.org/wikiupload/7/72/Typing_Template_Haskell_Soft_Types.ps ps]]<br />
<br />
= Other useful resources =<br />
<br />
* (2011) [https://github.com/leonidas/codeblog/blob/master/2011/2011-12-27-template-haskell.md Basic Tutorial of Template Haskell] <br />
<br />
* (2011) Greg Weber's [http://www.yesodweb.com/blog/2011/10/code-generation-conversation blog post on Template Haskell and quasi-quoting] in the context of Yesod.<br />
<br />
* (2012) Mike Ledger's [http://quasimal.com/posts/2012-05-25-quasitext-and-quasiquoting.html tutorial on TemplateHaskell and QuasiQuotation] for making an interpolated text QuasiQuoter. Here's another [http://www.well-typed.com/blog/2014/10/quasi-quoting-dsls/ great 2014 blog post on quasiquotation].<br />
<br />
<!-- * [http://www.haskell.org/th/ The old Template Haskell web page]. Would someone feel like moving this material into the HaskellWiki? <br />
--><br />
<!-- * Old and probably not too useful for most but maybe... http://www.cse.unsw.edu.au/~chak/haskell/ghc/comm/exts/th.html <br />
--><br />
* [http://www.cs.ox.ac.uk/people/ian.lynagh/Fraskell/ Fraskell documentation] & explanation of how Template Haskell is used to vastly speed it up.<br />
<br />
* [[Quasiquotation]]<br />
<br />
Feel free to update our Wikipedia entry http://en.wikipedia.org/wiki/Template_Haskell<br />
<br />
= Projects =<br />
<br />
What are you doing/planning to do/have done with Template Haskell?<br />
<br />
* The [http://www.ict.kth.se/org/ict/ecs/sam/projects/forsyde/www ForSyDe methodology] is currently implemented as a Haskell-based DSL which makes extensive use of Template Haskell.<br />
<br />
* I have written a primitive (untyped) binding to the Objective-C runtime system on Mac OS X. It needs just TH, no "stub files" are created, no separate utilities are required. Initial snapshot is at http://www.kfunigraz.ac.at/imawww/thaller/wolfgang/HOC020103.tar.bz2 -- WolfgangThaller<br />
<br />
* I am writing Template Greencard - a reimplementation of GreenCard using TH. Many bits work out really nicely. A few bits didn't work so nicely - once I get some time to think, I'll try to persuade the TH folk to make some changes to fix some of these. -- AlastairReid<br />
<br />
* I'm writing Hacanon - a framework for automatic generation of C++ bindings. Read "automated Template Greencard for C++" (-: Darcs repo: http://www.ScannedInAvian.org/repos/hacanon - You'll need gccxml (http://www.gccxml.org/) to compile the examples. - 27 Dec Lemmih.<br />
<br />
* Following other FFI tools developers, I see some future for Template HSFFIG, especially when it comes to autogenerate peek and poke methods for structures defined in C; may be useful for implementation of certain network protocols such as X11 where layout of messages is provided as C structure/union declaration. - 16 Dec 2005 DimitryGolubovsky<br />
<br />
* I am using Template Haskell as a mechanism to get parsed, typechecked code into an Ajax based Haskell Equational Reasoning tool [[Haskell Equational Reasoning Assistant]], as well as simplify the specification of equational relationships between pieces of code. There was a quicktime movie of the tool being used on http://www.gill-warbington.com/home/andy/share/hera1.html - AndyGill <br />
<br />
* I am working on functional metaprogramming techniques to enhance programming reliability and productivity, by reusing much of the existing compiler technology. Template Haskell is especially interesting for me because it permits to check size information of structures by the compiler, provided this information is available at compile time. This approach is especially appropriate for hardware designs, where the structures are fixed before the circuit starts operating. See our metaprogramming web page at http://www.infosun.fmi.uni-passau.de/cl/metaprog/ -- ChristophHerrmann(http://www.cs.st-and.ac.uk/~ch)<br />
<br />
* I am using Template Haskell to do type safe database access. I initially [http://www.nabble.com/Using-Template-Haskell-to-make-type-safe-database-access-td17027286.html proposed this on haskell-cafe]. I connect to the database at compile-time and let the database do SQL parsing and type inference. The result from parsing and type inference is used to build a type safe database query which can executed at run-time. [[MetaHDBC | You can find the project page here]] -- [mailto:mads_lindstroem@yahoo.dk Mads Lindstrøm]<br />
<br />
= Utilities =<br />
<br />
Helper functions, debugging functions, or more involved code e.g. a monadic fold algebra for TH.Syntax.<br />
<br />
* http://www.haskell.org/pipermail/template-haskell/2003-September/000176.html<br />
<br />
= Known Bugs =<br />
<br />
Take a look at the [http://hackage.haskell.org/trac/ghc/query?status=new&status=assigned&status=reopened&component=Template+Haskell&order=priority open bugs against Template Haskell] on the GHC bug tracker.<br />
<br />
= Wish list =<br />
<br />
Things that Ian Lynagh (Igloo) mentioned in his paper ''Template Haskell: A Report From The Field'' in May 2003 (available [http://www.haskell.org/wikiupload/2/24/Template_Haskell-A_Report_From_The_Field.ps here]), by section:<br />
<br />
* Section 2 (curses)<br />
** The ability to splice names (into "foreign import" declarations, in particular)<br />
** The ability to add things to the export list from a splice(?)<br />
** The ability to use things defined at the toplevel of a module from splices in that same module (would require multi-stage compilation, as opposed to the current approach of expanding splices during typechecking)<br />
<br />
* Section 3 (deriving instances of classes)<br />
** <strike>First-class reification</strike> (the <hask>reify</hask> function)<br />
** A way to discover whether a data constructor was defined infix or prefix (which is necessary to derive instances for <hask>Read</hask> and <hask>Show</hask> as outlined in [http://www.haskell.org/onlinereport/derived.html The Haskell 98 Report: Specification of Derived Instances]) (if there is a way, [http://community.haskell.org/~ndm/derive/ Derive] seems ignorant of it)<br />
** Type/context splicing (in <hask>instance</hask> headers in particular)<br />
<br />
* Section 4 (printf)<br />
** He says something to the effect that a pattern-matching form of the quotation brackets would be cool if it was expressive enough to be useful, but that this would be hard. (Don't expect this anytime soon.)<br />
<br />
* Section 5 (fraskell)<br />
** Type information for quoted code (so that simplification can be done safely even with overloaded operations, like, oh, <hask>(+)</hask>)<br />
<br />
* Section 6 (pan)<br />
** Type info again, and strictness info too (this one seems a bit pie-in-the-sky...)<br />
<br />
(Please leave the implemented ones here, but crossed off.)<br />
<br />
Any other features that may be nice, and TH projects you'd want to see.<br />
<br />
* A TH tutorial (mainly a distillation and update of ''Template Meta-programming in Haskell'' at this point)<br />
* <strike>Write Haddock documentation for the Template Haskell library (http://hackage.haskell.org/trac/ghc/ticket/1576).</strike><br />
* Make `reify` on a class return a list of the instances of that class (http://www.haskell.org/pipermail/template-haskell/2005-December/000503.html). (See also [http://hackage.haskell.org/trac/ghc/ticket/1577 GHC ticket #1577].)<br />
* A set of simple examples on this wiki page<br />
* A TH T-shirt with new logo to wear at conferences<br />
* (Long-term) Unify Language.Haskell.Syntax with Language.Haskell.TH.Syntax so there's just one way to do things (http://hackage.haskell.org/package/haskell-src-meta does a one-way translation, for haskell-src-exts)<br />
<br />
---------------<br />
<br />
= Tips and Tricks =<br />
<br />
== What to do when you can't splice that there ==<br />
<br />
When you try to splice something into the middle of a template and find that you just can't, instead of getting frustrated about it, why not use the template to see what it would look like in longhand? <br />
<br />
First, an excerpt from a module of my own. I, by the way, am SamB.<br />
<haskell><br />
{-# OPTIONS_GHC -fglasgow-exts -fth #-}<br />
<br />
module MMixMemory where<br />
<br />
import Data.Int<br />
import Data.Word<br />
<br />
class (Integral int, Integral word)<br />
=> SignConversion int word | int -> word, word -> int where<br />
<br />
toSigned :: word -> int<br />
toSigned = fromIntegral<br />
toUnsigned :: int -> word<br />
toUnsigned = fromIntegral<br />
<br />
</haskell><br />
<br />
Say I want to find out what I need to do to splice in the types for an instance declaration for the SignConversion class, so that I can declare instances for Int8 with Word8 through Int64 with Word64. So, I start up good-ol' GHCi and do the following:<br />
<br />
<haskell><br />
$ ghci -fth -fglasgow-exts<br />
Prelude> :l MMixMemory<br />
*MMixMemory> :m +Language.Haskell.TH.Syntax<br />
*MMixMemory Language.Haskell.TH.Syntax> runQ [d| instance SignConversion Int Word where |] >>= print<br />
[InstanceD [] (AppT (AppT (ConT MMixMemory.SignConversion) (ConT GHC.Base.Int)) (ConT GHC.Word.Word)) []]<br />
</haskell><br />
<br />
== What can <tt>reify</tt> see? ==<br />
<br />
When you use <tt>reify</tt> to give you information about a <tt>Name</tt>, GHC will tell you what it knows. But sometimes it doesn't know stuff. In particular<br />
<br />
* '''Imported things'''. When you reify an imported function, type constructor, class, etc, from (say) module M, GHC runs off to the interface file <tt>M.hi</tt> in which it deposited all the info it learned when compiling M. However, if you compiled M without optimisation (ie <tt>-O0</tt>, the default), and without <tt>-XTemplateHaskell</tt>, GHC tries to put as little info in the interface file as possible. (This is a possibly-misguided attempt to keep interface files small.) In particular, it may dump only the name and kind of a data type into <tt>M.hi</tt>, but not its constructors.<br />
: Under these circumstances you may reify a data type but get back no information about its data constructors or fields. Solution: compile M with <br />
:* <tt>-O</tt>, or<br />
:* <tt>-fno-omit-interface-pragmas</tt> (implied by -O), or<br />
:* <tt>-XTemplateHaskell</tt>.<br />
<br />
* '''Function definitions'''. The <tt>VarI</tt> constructor of the <tt>Info</tt> type advertises that you might get back the source code for a function definition. In fact, GHC currently (7.4) <em>always</em> returns <tt>Nothing</tt> in this field. It's a bit awkward and no one has really needed it.<br />
<br />
== Why does <tt>runQ</tt> crash if I try to reify something? ==<br />
<br />
This program will fail with an error message when you run it:<br />
<haskell><br />
main = do info <- runQ (reify (mkName "Bool")) -- more hygenic is: (reify ''Bool)<br />
putStrLn (pprint info)<br />
</haskell><br />
Reason: <tt>reify</tt> consults the type environment, and that is not available at run-time. The type of <tt>reify</tt> is <br />
<haskell><br />
reify :: Quasi m => Q a -> m a<br />
</haskell><br />
The IO monad is a poor-man's instance of <tt>Quasi</tt>; it can allocate unique names and gather error messages, but it can't do <tt>reify</tt>. This error should really be caught statically.<br />
<br />
Instead, you can run the splice directly (ex. in ghci -XTemplateHaskell), as the following shows:<br />
<br />
<haskell><br />
GHCi> let tup = $(tupE $ take 4 $ cycle [ [| "hi" |] , [| 5 |] ])<br />
GHCi> :type tup<br />
tup :: ([Char], Integer, [Char], Integer)<br />
<br />
GHCi> tup<br />
("hi",5,"hi",5)<br />
<br />
GHCi> $(stringE . show =<< reify ''Int)<br />
"TyConI (DataD [] GHC.Types.Int [] [NormalC GHC.Types.I# [(NotStrict,ConT GHC.Prim.Int#)]] [])"<br />
</haskell><br />
<br />
Here's an [http://www.haskell.org/pipermail/glasgow-haskell-users/2006-August/010844.html email thread with more details].<br />
<br />
-----------------<br />
<br />
= Examples =<br />
== Tuples ==<br />
=== Select from a tuple ===<br />
<br />
An example to select an element from a tuple of arbitrary size. Taken from [http://research.microsoft.com/en-us/um/people/simonpj/papers/meta-haskell/meta-haskell.pdf this paper].<br />
<br />
Use like so:<br />
<br />
> $(sel 2 3) ('a','b','c')<br />
'b'<br />
> $(sel 3 4) ('a','b','c','d')<br />
'c'<br />
<br />
<br />
<haskell><br />
sel :: Int -> Int -> ExpQ<br />
sel i n = [| \x -> $(caseE [| x |] [alt]) |]<br />
where alt :: MatchQ<br />
alt = match pat (normalB rhs) []<br />
<br />
pat :: Pat<br />
pat = tupP (map varP as)<br />
<br />
rhs :: ExpQ<br />
rhs = varE(as !! (i -1)) -- !! is 0 based<br />
<br />
as :: [String]<br />
as = ["a" ++ show i | i <- [1..n] ]<br />
</haskell><br />
<br />
Alternately:<br />
<br />
<haskell><br />
sel' i n = lamE [pat] rhs<br />
where pat = tupP (map varP as)<br />
rhs = varE (as !! (i - 1))<br />
as = [ "a" ++ show j | j <- [1..n] ]<br />
</haskell><br />
<br />
=== Apply a function to the n'th element ===<br />
<br />
<haskell><br />
tmap i n = do<br />
f <- newName "f"<br />
as <- replicateM n (newName "a")<br />
lamE [varP f, tupP (map varP as)] $<br />
tupE [ if i == i'<br />
then [| $(varE f) $a |]<br />
else a<br />
| (a,i') <- map varE as `zip` [1..] ]<br />
</haskell><br />
<br />
Then tmap can be called as:<br />
<br />
> $(tmap 3 4) (+ 1) (1,2,3,4)<br />
(1,2,4,4)<br />
<br />
=== Convert the first n elements of a list to a tuple ===<br />
<br />
This example creates a tuple by extracting elements from a list. Taken from<br />
[http://www.xoltar.org/2003/aug/13/templateHaskellTupleSample.html www.xoltar.org]<br />
<br />
Use like so:<br />
<br />
> $(tuple 3) [1,2,3,4,5]<br />
(1,2,3)<br />
> $(tuple 2) [1,2]<br />
(1,2)<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = [|\list -> $(tupE (exprs [|list|])) |]<br />
where<br />
exprs list = [infixE (Just (list))<br />
(varE "!!")<br />
(Just (litE $ integerL (toInteger num)))<br />
| num <- [0..(n - 1)]]<br />
</haskell><br />
<br />
An alternative that has more informative errors (a failing pattern match failures give an exact location):<br />
<br />
<haskell><br />
tuple :: Int -> ExpQ<br />
tuple n = do<br />
ns <- replicateM n (newName "x")<br />
lamE [foldr (\x y -> conP '(:) [varP x,y]) wildP ns] (tupE $ map varE ns)<br />
</haskell><br />
<br />
=== Un-nest tuples ===<br />
Convert nested tuples like (a,(b,(c,()))) into (a,b,c) given the length to generate.<br />
<br />
<haskell><br />
unNest n = do<br />
vs <- replicateM n (newName "x")<br />
lamE [foldr (\a b -> tupP [varP a , b])<br />
(conP '() [])<br />
vs]<br />
(tupE (map varE vs))<br />
</haskell><br />
<br />
<br />
<br />
== [[Template Haskell/Marshall Data|Marshall a datatype to and from Dynamic]] ==<br />
This approach is an example of using template haskell to delay typechecking<br />
to be able to abstract out the repeated calls to fromDynamic:<br />
<br />
<haskell><br />
data T = T Int String Double<br />
<br />
toT :: [Dynamic] -> Maybe T<br />
toT [a,b,c] = do<br />
a' <- fromDynamic a<br />
b' <- fromDynamic b<br />
c' <- fromDynamic c<br />
return (T a' b' c')<br />
toT _ = Nothing<br />
</haskell><br />
<br />
== Printf ==<br />
Build it using a command similar to:<br />
<br />
ghc --make Main.hs -o main<br />
<br />
Main.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
<br />
-- Import our template "printf"<br />
import PrintF (printf)<br />
<br />
-- The splice operator $ takes the Haskell source code<br />
-- generated at compile time by "printf" and splices it into<br />
-- the argument of "putStrLn".<br />
main = do<br />
putStrLn $ $(printf "Hello %s %%x%% %d %%x%%") "World" 12<br />
</haskell><br />
<br />
PrintF.hs:<br />
<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
module PrintF where<br />
<br />
-- NB: printf needs to be in a separate module to the one where<br />
-- you intend to use it.<br />
<br />
-- Import some Template Haskell syntax<br />
import Language.Haskell.TH<br />
<br />
-- Possible string tokens: %d %s and literal strings<br />
data Format = D | S | L String<br />
deriving Show<br />
<br />
-- a poor man's tokenizer<br />
tokenize :: String -> [Format]<br />
tokenize [] = []<br />
tokenize ('%':c:rest) | c == 'd' = D : tokenize rest<br />
| c == 's' = S : tokenize rest<br />
tokenize (s:str) = L (s:p) : tokenize rest -- so we don't get stuck on weird '%'<br />
where (p,rest) = span (/= '%') str<br />
<br />
-- generate argument list for the function<br />
args :: [Format] -> [PatQ]<br />
args fmt = concatMap (\(f,n) -> case f of<br />
L _ -> []<br />
_ -> [varP n]) $ zip fmt names<br />
where names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- generate body of the function<br />
body :: [Format] -> ExpQ<br />
body fmt = foldr (\ e e' -> infixApp e [| (++) |] e') (last exps) (init exps)<br />
where exps = [ case f of<br />
L s -> stringE s<br />
D -> appE [| show |] (varE n)<br />
S -> varE n<br />
| (f,n) <- zip fmt names ]<br />
names = [ mkName $ 'x' : show i | i <- [0..] ]<br />
<br />
-- glue the argument list and body together into a lambda<br />
-- this is what gets spliced into the haskell code at the call<br />
-- site of "printf"<br />
printf :: String -> Q Exp<br />
printf format = lamE (args fmt) (body fmt)<br />
where fmt = tokenize format<br />
</haskell><br />
<br />
== Handling Options with Templates ==<br />
A common idiom for treating a set of options, e.g. from GetOpt, is to define a datatype with all the flags and using a list over this datatype:<br />
<br />
<haskell><br />
data Options = B1 | B2 | V Integer<br />
<br />
options = [B1, V 3]<br />
</haskell><br />
<br />
While it's simple testing if a Boolean flag is set (simply use "elem"), it's harder to check if an option with an argument is set. It's even more tedious writing helper-functions to obtain the value from such an option since you have to explicitely "un-V" each. Here, Template Haskell can be (ab)used to reduce this a bit. The following example provides the module "OptionsTH" which can be reused regardless of the constructors in "Options". Let's start with showing how we'd like to be able to program. Notice that the resulting lists need some more treatment e.g. through "foldl".<br />
<br />
Options.hs:<br />
<br />
<haskell><br />
module Main where<br />
<br />
import OptionsTH<br />
import Language.Haskell.TH.Syntax<br />
<br />
data Options = B1 | B2 | V Int | S String deriving (Eq, Read, Show)<br />
<br />
options = [B1, V 3]<br />
<br />
main = do<br />
print foo -- test if B1 set: [True,False]<br />
print bar -- test if V present, w/o value: [False,True]<br />
print baz -- get value of V if available: [Nothing,Just 3]<br />
<br />
foo :: [Bool]<br />
-- Query constructor B1 which takes no arguments<br />
foo = map $(getopt (THNoArg (mkArg "B1" 0))) options<br />
<br />
bar :: [Bool]<br />
-- V is a unary constructor. Let mkArg generate the required<br />
-- wildcard-pattern "V _".<br />
bar = map $(getopt (THNoArg (mkArg "V" 1))) options<br />
<br />
-- Can't use a wildcard here!<br />
baz :: [(Maybe Int)]<br />
baz = map $(getopt (THArg (conP "V" [varP "x"]))) options<br />
</haskell><br />
<br />
OptionsTH.hs<br />
<br />
<haskell><br />
module OptionsTH where<br />
<br />
import Language.Haskell.TH.Syntax<br />
<br />
-- datatype for querying options:<br />
-- NoArg: Not interested in value (also applies to Boolean flags)<br />
-- Arg: Grep value of unary(!) constructor<br />
data Args = THNoArg Pat | THArg Pat<br />
<br />
getopt :: Args -> ExpQ<br />
getopt (THNoArg pat) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB [| True |]) []<br />
cons1 = match wildP (normalB [| False |]) []<br />
<br />
-- bind "var" for later use!<br />
getopt (THArg pat@(ConP _ [VarP var])) = lamE [varP "y"] (caseE (varE "y") [cons0, cons1])<br />
where<br />
cons0 = match pat (normalB (appE [|Just|] (varE var))) []<br />
cons1 = match wildP (normalB [|Nothing|]) []<br />
<br />
mkArg :: String -> Int -> Pat<br />
mkArg k c = conP k (replicate c wildP)<br />
</haskell><br />
<br />
While the example might look contrived for the Boolean options which could have been tested much easier, it shows how both types of arguments can be treated in a similar way.<br />
<br />
=== Limitations ===<br />
<tt>getopt (THArg pat)</tt> is only able to treat unary constructors. See the pattern-binding: It matches exactly a single VarP.<br />
<br />
=== Improvements ===<br />
The following reduces things even a bit more, though I still don't know if I like it. It only works since <tt>c</tt> is either 0 or 1.<br />
<br />
<haskell><br />
mkArg k c = conP k (replicate c (varP "x"))<br />
<br />
baz = map $(getopt (THArg (mkArg "V" 1)))<br />
</haskell><br />
-- VolkerStolz<br />
<br />
== Generic constructor for records ==<br />
<br />
I have a large number of record types like this, of different length:<br />
<br />
<haskell><br />
data PGD = PGD {<br />
pgdXUnitBase :: !Word8,<br />
pgdYUnitBase :: !Word8,<br />
pgdXLUnitsperUnitBase :: !Word16<br />
}<br />
</haskell><br />
<br />
Currently I use GHC's Binary module to read them from files; it can handle<br />
types like <tt>(Word8, (Word8, Word16))</tt>, but there was no easy way to generate<br />
the correct amount of "uncurry" calls for automatically grabbing each element.<br />
<br />
With Template Haskell, the instance declarations are now written as such:<br />
<br />
<haskell><br />
instance Binary PGD where<br />
get bh = do a <- get bh ; return $ $(constrRecord PGD) a<br />
</haskell><br />
<br />
Here the trick lies in constrRecord, which is defined as:<br />
<br />
<haskell><br />
constrRecord x = reify exp where<br />
reify = \(Just r) -> appE r $ conE $ last args<br />
exp = foldl (dot) uncur $ replicate terms uncur<br />
terms = ((length args) `div` 2) - 2<br />
dot x y = (Just $ infixE x (varE ".") y)<br />
uncur = (Just [|uncurry|])<br />
args = words . show $ typeOf x<br />
</haskell><br />
<br />
-- AutrijusTang<br />
<br />
== zipWithN ==<br />
<br />
Here $(zipn 3) = zipWith3 etc.<br />
<br />
<haskell><br />
import Language.Haskell.TH; import Control.Applicative; import Control.Monad<br />
<br />
zipn n = do<br />
vs <- replicateM n (newName "vs")<br />
[| \f -><br />
$(lamE (map varP vs)<br />
[| getZipList $<br />
$(foldl<br />
(\a b -> [| $a <*> $b |])<br />
[| pure f |]<br />
(map (\v -> [| ZipList $(varE v) |]) vs))<br />
|])<br />
|]<br />
</haskell><br />
<br />
== 'generic' zipWith ==<br />
A generalization of zipWith to almost any data. Demonstrates the ability to do dynamic binding with TH splices (note 'dyn').<br />
<br />
<haskell><br />
zipCons :: Name -> Int -> [String] -> ExpQ<br />
zipCons tyName ways functions = do<br />
let countFields :: Con -> (Name,Int)<br />
countFields x = case x of<br />
NormalC n (length -> fields) -> (n, fields)<br />
RecC n (length -> fields) -> (n,fields)<br />
InfixC _ n _ -> (n,2)<br />
ForallC _ _ ct -> countFields ct<br />
<br />
TyConI (DataD _ _ _ [countFields -> (c,n)] _) <- reify tyName<br />
when (n /= length functions) $ fail "wrong number of functions named"<br />
vs <- replicateM ways $ replicateM n $ newName "x"<br />
lamE (map (conP c . map varP) vs) $<br />
foldl (\con (vs,f) -><br />
con `appE`<br />
foldl appE<br />
(dyn f)<br />
(map varE vs))<br />
(conE c)<br />
(transpose vs `zip` functions)<br />
</haskell><br />
<br />
This example uses whichever '+' is in scope when the expression is spliced:<br />
<br />
<haskell><br />
:type $(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
<br />
$(zipCons ''(,,,) 2 (replicate 4 "+"))<br />
:: (Num t, Num t1, Num t2, Num t3) =><br />
(t, t1, t2, t3) -> (t, t1, t2, t3) -> (t, t1, t2, t3)<br />
</haskell><br />
<br />
==[[Template haskell/Instance deriving example|Instance deriving example]]==<br />
An example using a 'deriving function' to generate a method instance <br />
per constructor of a type. The deriving function provides the body of the<br />
method.<br />
<br />
Note that this example assumes that the functions of the class take a parameter that is the same type as instance is parameterized with. <br />
<br />
The message [http://www.haskell.org/pipermail/template-haskell/2006-August/000581.html email message] contains the full source ([http://www.iist.unu.edu/~vs/haskell/TH_render.hs extracted file]).<br />
<br />
== [[Quasiquotation|QuasiQuoters]] ==<br />
New in ghc-6.10 is -XQuasiQuotes, which allows one to extend GHC's syntax from library code. Quite a few examples were previously part of older [http://hackage.haskell.org/package/haskell-src-meta-0.2 haskell-src-meta]. Some of these are now part of [http://hackage.haskell.org/package/applicative-quoters applicative-quoters]<br />
<br />
=== Similarity with splices ===<br />
<br />
Quasiquoters used in expression contexts (those using the ''quoteExp'') behave to a first approximation like regular TH splices:<br />
<br />
<haskell><br />
simpleQQ = QuasiQuoter { quoteExp = stringE } -- in another module<br />
<br />
[$simpleQQ| a b c d |] == $(quoteExp simpleQQ " a b c d ")<br />
</haskell><br />
<br />
== Generating records which are variations of existing records ==<br />
This example uses syb to address some of the pain of dealing with the rather large data types. <br />
<br />
<haskell><br />
{-# LANGUAGE ScopedTypeVariables, TemplateHaskell #-}<br />
module A where<br />
import Language.Haskell.TH<br />
import Data.Generics<br />
<br />
addMaybes modName input = let<br />
<br />
rename :: GenericT<br />
rename = mkT $ \n -> if nameModule n == modName<br />
then mkName $ nameBase n ++ "_opt"<br />
else n<br />
<br />
addMaybe :: GenericM Q<br />
addMaybe = mkM $ \(n :: Name, s :: Strict, ty :: Type) -> do<br />
ty' <- [t| Maybe $(return ty) |]<br />
return (n,s,ty')<br />
<br />
in everywhere rename `fmap` everywhereM addMaybe input<br />
<br />
mkOptional :: Name -> Q Dec<br />
mkOptional n = do<br />
TyConI d <- reify n<br />
addMaybes (nameModule n) d<br />
</haskell><br />
<br />
mkOptional then generates a new data type with all Names in that module with an added suffix _opt. Here is an example of its use:<br />
<haskell><br />
{-# LANGUAGE TemplateHaskell #-}<br />
import A<br />
data Foo = Foo { a,b,c,d,e :: Double, f :: Int }<br />
<br />
mapM mkOptional [''Foo]<br />
</haskell><br />
<br />
Generates something like<br />
<haskell><br />
data Foo_opt = Foo_opt {a_opt :: Maybe Double, ..... f_opt :: Maybe Int}<br />
</haskell><br />
<br />
<br />
<br />
[[Category:Language extensions]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Command_line_option_parsers&diff=62109Command line option parsers2017-08-31T21:45:26Z<p>Enoksrd: Say when download stats were gathered.</p>
<hr />
<div>There are several packages that want to simplify the task of writing command line parsers. Unfortunately, they are distributed across several Hackage categories. Here is an attempt to list them.<br />
<br />
Based on Hackage downloads, as of May 2017, cmdargs (126k downloads) and optparse-applicative (120k downloads) are the most popular.<br />
<br />
{| class="wikitable" border="1" style="border-collapse:collapse"<br />
|-<br />
! Package !! Multi-mode !! Extensions !! Remark<br />
|-<br />
| {{HackagePackage|id=argparser}} || - || None (though it depends on package containers, which uses extensions) || <br />
|-<br />
| {{HackagePackage|id=cmdargs}} || X || TemplateHaskell, SYB generics, ViewPatterns, ... || <hask>unsafePerformIO</hask><br />
|-<br />
| {{HackagePackage|id=cmdlib}} || X || SYB generics || based on [[GetOpt]]<br />
|-<br />
| {{HackagePackage|id=cmdtheline}} || X || FlexibleInstances (although unnecessary) || shows help as man-page<br />
|-<br />
| {{HackagePackage|id=console-program}} || X || (none) || configure options via files<br />
|-<br />
| {{HackagePackage|id=getflag}} || - || Haskell98 || like [[GetOpt]] but with Unix/Plan 9 option syntax<br />
|-<br />
| {{HackagePackage|id=hflags}} || - || TemplateHaskell || inspired by Google's gflags, provides parsed options in top-level variables, allow to set options via environment variables<br />
|-<br />
| {{HackagePackage|id=multiarg}} || - || CPP || long options with multiple arguments<br />
|-<br />
| {{HackagePackage|id=options}} || X || ||<br />
|-<br />
| {{HackagePackage|id=optparse-applicative}} || X || GADT || Applicative Functor; for wrong arguments it does not show a specific error message but the general usage pattern<br />
|-<br />
| {{HackagePackage|id=parseargs}} || - || FlexibleInstances (although unnecessary) || supports a fixed set of argument types: <hask>Int, Integer, Float, Double, String, FileOpener</hask><br />
|-<br />
| {{HackagePackage|id=ReadArgs}} || - || OverlappingInstances, TypeOperators || No options, only arguments. The argument template is derived from the requested argument tuple.<br />
|-<br />
| {{HackagePackage|id=simpleargs}} || - || OverlappingInstances (although unnecessary) || the same as ReadArgs<br />
|-<br />
| {{HackagePackage|id=uu-options}} || - || || Uses the less popular data-lens. Error correction.<br />
|}<br />
<br />
The column for required Haskell extensions gives an idea of how easy it is to port the package to compilers other than [[GHC]].<br />
<br />
<br />
[[Category:Packages]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Package_versioning_policy&diff=59699Package versioning policy2015-04-28T20:26:51Z<p>Enoksrd: Add a link to the similar semantic versioning standard.</p>
<hr />
<div>== Rationale ==<br />
<br />
The goal of a versioning system is to inform clients of a package of changes to that package that might affect them, and to provide a way for clients to specify a particular version or range of versions of a dependency that they are compatible with.<br />
<br />
[http://haskell.org/cabal Cabal] provides the raw materials for versioning: it allows packages to specify their own version, and it allows dependencies that specify which versions of the dependent package are acceptable. Cabal will select dependencies based on the constraints.<br />
<br />
What is missing from this picture is a ''policy'' that tells the library developer how to set their version numbers, and tells a client how to write a dependency that means their package will not try to compile against an incompatible dependency. For some time there has been an informal policy in use in the Haskell community, but it became clear that we were running into trouble with incorrectly-specified dependencies and unbuildable packages, so this page is an attempt to formalize the policy.<br />
<br />
== Version numbers ==<br />
<br />
A package version number should have the form ''A.B.C'', and may optionally have any number of additional components, for example 2.1.0.4 (in this case, ''A''=2, ''B''=1, ''C=0''). This policy defines the meaning of the first three components ''A-C'', the other components can be used in any way the package maintainer sees fit.<br />
<br />
Version number ordering is already defined by Cabal as the lexicographic ordering of the components. For example, 2.1 > 1.3, and 2.1.1 > 2.1. (The <tt>Data.Version.Version</tt> type and its <tt>Ord</tt> instance embody this ordering).<br />
<br />
''A.B'' is known as the ''major'' version number, and ''C'' the ''minor'' version number. When a package is updated, the following rules govern how the version number must change relative to the previous version:<br />
<br />
# If any entity was removed, or the types of any entities or the definitions of datatypes or classes were changed, or [[orphan instance]]s were added or any instances were removed, then the new ''A.B'' must be greater than the previous ''A.B''. Note that modifying imports or depending on a newer version of another package may cause extra orphan instances to be exported and thus force a major version change.<br />
# Otherwise, if only new bindings, types, classes, non-orphan instances or modules (but see below) were added to the interface, then ''A.B'' may remain the same but the new ''C'' must be greater than the old ''C''. Note that modifying imports or depending on a newer version of another package may cause extra non-orphan instances to be exported and thus force a minor version change.<br />
# Otherwise, ''A.B.C'' may remain the same (other version components may change).<br />
<br />
Hence ''A.B.C'' uniquely identifies the API. A client that wants to specify that they depend on a particular version of the API can specify a particular ''A.B.C'' and be sure of getting that API only. For example, <tt>build-depends: mypkg >= 2.1.1 && < 2.1.2</tt>.<br />
<br />
Often a package maintainer wants to add to an API without breaking backwards compatibility, and in that case they can follow the rules of point 2, and increase only ''C''. A client can specify that they are [[Import modules properly|insensitive to additions to the API]] by allowing a range of ''C'' values, e.g. <tt>build-depends: base >= 2.1.1 && < 2.2</tt>.<br />
<br />
If a package defines an orphan instance, it must depend on the minor version of the packages that define the data type and the type class to be backwards compatible. For example, <tt>build-depends: mypkg >= 2.1.1 && < 2.1.2</tt>.<br />
<br />
=== Deprecation ===<br />
<br />
Deprecated entities (via a <tt>DEPRECATED</tt> pragma) should probably be counted as removed for the purposes of upgrading the API, because packages that use <tt>-Werror</tt> will be broken by the deprecation.<br />
<br />
=== Adding new modules ===<br />
<br />
Adding new modules might cause an unavoidable name collision in dependent code. However, this is usually pretty unlikely, especially if you keep to your own namespace, so only an increase of the minor version number is required. If, however, your added module name is taken from another package (e.g. when <tt>network-bytestring</tt> was merged into <tt>network</tt>) or is quite general (<tt>Data.Set</tt> or something similar) then the version increase should be major.<br />
<br />
=== Leaking instances ===<br />
<br />
There is a case where addition or removal of an instance in a package, that the user doesn't depend on directly, can still lead to compilation failures. Consider these three packages:<br />
<br />
Package A:<br />
<haskell><br />
module PackageA where<br />
<br />
class Monad m => MonadLogger m<br />
instance MonadLogger IO<br />
</haskell><br />
<br />
Package B, depends on package A:<br />
<haskell><br />
module PackageB where<br />
<br />
import PackageA<br />
<br />
f :: MonadLogger m => Int -> m String<br />
f = return . show<br />
</haskell><br />
<br />
Package C, depends on package B:<br />
<haskell><br />
module Package C where<br />
<br />
import PackageB<br />
<br />
main :: IO ()<br />
main = f 5 >>= print<br />
</haskell><br />
<br />
Now consider this scenario:<br />
<br />
# Package A removes the <hask>IO</hask> instance and gets its major version number bumped, as required by the PVP.<br />
# Package B, which can still work with the old and new version of package A, changes its dependency on package A to allow for both versions. Package B only gets a patch-level bump.<br />
# Package C might or might not compile, depending on which patch-level version of package B is used.<br />
<br />
The PVP could require that package B bumps its major version number as it now (re-)exports one fewer instances. This will however require more frequent version bumps in the whole ecosystem. As a pragmatic solution, for now the PVP doesn't required a major version bump in this case and instead leaves it to package C to add a dependency on package A to handle this situation.<br />
<br />
=== Version tags ===<br />
<br />
The components of the version number must be numbers! Historically Cabal supported version numbers with string tags at the end, e.g. <tt>1.0-beta</tt> This proved not to work well because the ordering for tags was not well defined. Version tags are [https://github.com/haskell/cabal/issues/890 no longer supported] and mostly ignored, however some tools will fail in some circumstances if they encounter them.<br />
<br />
This can sometimes trip you up if you accidentally stumble into using the deprecated tags syntax without realising it, for example a version number with a date like <tt>1.0.2014-01-27</tt> would be interpreted as the version <tt>1.0.2014</tt> with tags <tt>01</tt> and <tt>27</tt>.<br />
<br />
== Dependencies in Cabal ==<br />
<br />
When publishing a Cabal package, you should ensure that your dependencies in the <tt>build-depends</tt> field are accurate. This means specifying not only lower bounds, but also upper bounds on every dependency. <br />
<br />
At some point in the future, Hackage may refuse to accept packages that do not follow this convention. The aim is that before this happens, we will put in place tool support that makes it easier to follow the convention and less painful when dependencies are updated.<br />
<br />
To minimize breakage when new package versions are released, you can use dependencies that are insensitive to minor version changes (e.g. <tt>foo >= 1.2.1 && < 1.3</tt>). However, note that this approach is slightly risky: when a package exports more things than before, there is a chance that your code will fail to compile due to new name-clash errors. The risk from new name clashes may be small, but you are on the safe side if you [[Import modules properly|import identifiers explicitly or using qualification]].<br />
<br />
== Version syntax ==<br />
<br />
Since Cabal 1.6, you can specify an exact API version according to this policy with the special syntax <tt>package == 1.1.4.*</tt> or an API version up to additions with <tt>package == 1.1.*</tt>. The former translates into <tt>package >= 1.1.4 && < 1.1.5</tt>, for example - notice that 1.1.4 ''is'' included, rather than just including 1.1.4.0.<br />
<br />
== Tools ==<br />
<br />
* script to check for API changes in gtk2hs: http://code.haskell.org/gtk2hs/tools/apidiff/<br />
* [http://hackage.haskell.org/package/precis precis] - a simple tool for a first approximation of package API differences, see the [http://www.haskell.org/pipermail/haskell-cafe/2010-April/077023.html announcement]<br />
* {{HackagePackage|id=check-pvp}} is a program that checks for consistency between package dependencies and import style.<br />
<br />
== Related ==<br />
<br />
* [[Sven Moritz Hallberg]], "[[The_Monad.Reader/Issue2/EternalCompatibilityInTheory|Eternal compatibility in theory]]," [[The Monad.Reader]], [[The Monad.Reader/Issue2|Issue 2]]<br />
* [http://semver.org/ Semantic Versioning] is similar, but allows for version tags and defines how tags affect the ordering.</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Package_versioning_policy&diff=57486Package versioning policy2014-01-25T08:26:44Z<p>Enoksrd: /* Warning! */ Link to bug report on GitHub.</p>
<hr />
<div>== Rationale ==<br />
<br />
The goal of a versioning system is to inform clients of a package of changes to that package that might affect them, and to provide a way for clients to specify a particular version or range of versions of a dependency that they are compatible with.<br />
<br />
[http://haskell.org/cabal Cabal] provides the raw materials for versioning: it allows packages to specify their own version, and it allows dependencies that specify which versions of the dependent package are acceptable. Cabal will select dependencies based on the constraints.<br />
<br />
What is missing from this picture is a ''policy'' that tells the library developer how to set their version numbers, and tells a client how to write a dependency that means their package will not try to compile against an incompatible dependency. For some time there has been an informal policy in use in the Haskell community, but it became clear that we were running into trouble with incorrectly-specified dependencies and unbuildable packages, so this page is an attempt to formalize the policy.<br />
<br />
== Version numbers ==<br />
<br />
A package version number should have the form ''A.B.C'', and may optionally have any number of additional components, for example 2.1.0.4 (in this case, ''A''=2, ''B''=1, ''C=0''). This policy defines the meaning of the first three components ''A-C'', the other components can be used in any way the package maintainer sees fit.<br />
<br />
Version number ordering is already defined by Cabal as the lexicographic ordering of the components. For example, 2.1 > 1.3, and 2.1.1 > 2.1. (The <tt>Data.Version.Version</tt> type and its <tt>Ord</tt> instance embody this ordering).<br />
<br />
''A.B'' is known as the ''major'' version number, and ''C'' the ''minor'' version number. When a package is updated, the following rules govern how the version number must change relative to the previous version:<br />
<br />
# If any entity was removed, or the types of any entities or the definitions of datatypes or classes were changed, or instances were added or removed, then the new ''A.B'' must be greater than the previous ''A.B''. Note that modifying imports or depending on a newer version of another package may cause extra instances to be exported and thus force a major version change.<br />
# Otherwise, if only new bindings, types, classes or modules (but see below) were added to the interface, then ''A.B'' may remain the same but the new ''C'' must be greater than the old ''C''.<br />
# Otherwise, ''A.B.C'' may remain the same (other version components may change).<br />
<br />
Hence ''A.B.C'' uniquely identifies the API. A client that wants to specify that they depend on a particular version of the API can specify a particular ''A.B.C'' and be sure of getting that API only. For example, <tt>build-depends: mypkg >= 2.1.1 && < 2.1.2</tt>.<br />
<br />
Often a package maintainer wants to add to an API without breaking backwards compatibility, and in that case they can follow the rules of point 2, and increase only ''C''. A client can specify that they are [[Import modules properly|insensitive to additions to the API]] by allowing a range of ''C'' values, e.g. <tt>build-depends: base >= 2.1.1 && < 2.2</tt>.<br />
<br />
=== Warning! ===<br />
<br />
The components of the version number should be numbers! Recent versions of Cabal (1.18.1.2 as I write this) have (undocumented?) [http://hackage.haskell.org/package/base-4.6.0.1/docs/src/Data-Version.html#parseVersion support for "tags" in version numbers], but they seem to cause problems for <tt>cabal-install</tt> (1.18.0.2 as I write this). So, e.g., if you decide to make version numbers like ''A.B.C.YYYY-MM-DD'' you will have mysterious problems, such as<br />
<br />
$ cabal install<br />
[...]<br />
cabal: Distribution/Simple/PackageIndex.hs:126:8-13: Assertion failed<br />
<br />
when you try to reinstall your package (I'm using a Cabal sandbox; I'm not sure if that's relevant).<br />
<br />
(There is an [https://github.com/haskell/cabal/issues/890?source=cc associated bug] on the Cabal GitHub, but I'm also making a note here since the <tt><package>.cabal</tt> comments generated by <tt>cabal init</tt> tell you to see this wiki page for package version documentation).<br />
<br />
=== Deprecation ===<br />
<br />
Deprecated entities (via a DEPRECATED pragma) should probably be counted as removed for the purposes of upgrading the API, because packages that use <tt>-Werror</tt> will be broken by the deprecation.<br />
<br />
=== Adding new modules ===<br />
<br />
Adding new modules might cause an unavoidable name collision in dependent code. However, this is usually pretty unlikely, especially if you keep to your own namespace, so only an increase of the minor version number is required. If, however, your added module name is taken from another package (e.g. when <tt>network-bytestring</tt> was merged into <tt>network</tt>) or is quite general (Data.Set or something similar) then the version increase should be major.<br />
<br />
== Dependencies in Cabal ==<br />
<br />
When publishing a Cabal package, you should ensure that your dependencies in the <tt>build-depends</tt> field are accurate. This means specifying not only lower bounds, but also upper bounds on every dependency. <br />
<br />
At some point in the future, Hackage may refuse to accept packages that do not follow this convention. The aim is that before this happens, we will put in place tool support that makes it easier to follow the convention and less painful when dependencies are updated.<br />
<br />
To minimize breakage when new package versions are released, you can use dependencies that are insensitive to minor version changes (e.g. <tt>foo >= 1.2.1 && < 1.3</tt>). However, note that this approach is slightly risky: when a package exports more things than before, there is a chance that your code will fail to compile due to new name-clash errors. The risk from new name clashes may be small, but you are on the safe side if you [[Import modules properly|import identifiers explicitly or using qualification]].<br />
<br />
== Version syntax ==<br />
<br />
Since Cabal 1.6, you can specify an exact API version according to this policy with the special syntax <tt>package == 1.1.4.*</tt> or an API version up to additions with <tt>package == 1.1.*</tt>. The former translates into <tt>package >= 1.1.4 && < 1.1.5</tt>, for example - notice that 1.1.4 ''is'' included, rather than just including 1.1.4.0.<br />
<br />
== Tools ==<br />
<br />
* script to check for API changes in gtk2hs: http://code.haskell.org/gtk2hs/tools/apidiff/<br />
* [http://hackage.haskell.org/package/precis precis] - a simple tool for a first approximation of package API differences, see the [http://www.haskell.org/pipermail/haskell-cafe/2010-April/077023.html announcement]<br />
<br />
== Related ==<br />
<br />
* [[Sven Moritz Hallberg]], "[[The_Monad.Reader/Issue2/EternalCompatibilityInTheory|Eternal compatibility in theory]]," [[The Monad.Reader]], [[The Monad.Reader/Issue2|Issue 2]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Package_versioning_policy&diff=57485Package versioning policy2014-01-25T08:12:29Z<p>Enoksrd: /* Version numbers */ Note a confusing version number bug in recent Cabal.</p>
<hr />
<div>== Rationale ==<br />
<br />
The goal of a versioning system is to inform clients of a package of changes to that package that might affect them, and to provide a way for clients to specify a particular version or range of versions of a dependency that they are compatible with.<br />
<br />
[http://haskell.org/cabal Cabal] provides the raw materials for versioning: it allows packages to specify their own version, and it allows dependencies that specify which versions of the dependent package are acceptable. Cabal will select dependencies based on the constraints.<br />
<br />
What is missing from this picture is a ''policy'' that tells the library developer how to set their version numbers, and tells a client how to write a dependency that means their package will not try to compile against an incompatible dependency. For some time there has been an informal policy in use in the Haskell community, but it became clear that we were running into trouble with incorrectly-specified dependencies and unbuildable packages, so this page is an attempt to formalize the policy.<br />
<br />
== Version numbers ==<br />
<br />
A package version number should have the form ''A.B.C'', and may optionally have any number of additional components, for example 2.1.0.4 (in this case, ''A''=2, ''B''=1, ''C=0''). This policy defines the meaning of the first three components ''A-C'', the other components can be used in any way the package maintainer sees fit.<br />
<br />
Version number ordering is already defined by Cabal as the lexicographic ordering of the components. For example, 2.1 > 1.3, and 2.1.1 > 2.1. (The <tt>Data.Version.Version</tt> type and its <tt>Ord</tt> instance embody this ordering).<br />
<br />
''A.B'' is known as the ''major'' version number, and ''C'' the ''minor'' version number. When a package is updated, the following rules govern how the version number must change relative to the previous version:<br />
<br />
# If any entity was removed, or the types of any entities or the definitions of datatypes or classes were changed, or instances were added or removed, then the new ''A.B'' must be greater than the previous ''A.B''. Note that modifying imports or depending on a newer version of another package may cause extra instances to be exported and thus force a major version change.<br />
# Otherwise, if only new bindings, types, classes or modules (but see below) were added to the interface, then ''A.B'' may remain the same but the new ''C'' must be greater than the old ''C''.<br />
# Otherwise, ''A.B.C'' may remain the same (other version components may change).<br />
<br />
Hence ''A.B.C'' uniquely identifies the API. A client that wants to specify that they depend on a particular version of the API can specify a particular ''A.B.C'' and be sure of getting that API only. For example, <tt>build-depends: mypkg >= 2.1.1 && < 2.1.2</tt>.<br />
<br />
Often a package maintainer wants to add to an API without breaking backwards compatibility, and in that case they can follow the rules of point 2, and increase only ''C''. A client can specify that they are [[Import modules properly|insensitive to additions to the API]] by allowing a range of ''C'' values, e.g. <tt>build-depends: base >= 2.1.1 && < 2.2</tt>.<br />
<br />
=== Warning! ===<br />
<br />
The components of the version number should be numbers! Recent versions of Cabal (1.18.1.2 as I write this) have (undocumented?) [http://hackage.haskell.org/package/base-4.6.0.1/docs/src/Data-Version.html#parseVersion support for "tags" in version numbers], but they seem to cause problems for <tt>cabal-install</tt> (1.18.0.2 as I write this). So, e.g., if you decide to make version numbers like ''A.B.C.YYYY-MM-DD'' you will have mysterious problems, such as<br />
<br />
$ cabal install<br />
[...]<br />
cabal: Distribution/Simple/PackageIndex.hs:126:8-13: Assertion failed<br />
<br />
when you try to reinstall your package (I'm using a Cabal sandbox; I'm not sure if that's relevant).<br />
<br />
(I will report a bug on GitHub, but I'm also making a note here since the <tt><package>.cabal</tt> comments generated by <tt>cabal init</tt> tell you to see this wiki page for package version documentation).<br />
<br />
=== Deprecation ===<br />
<br />
Deprecated entities (via a DEPRECATED pragma) should probably be counted as removed for the purposes of upgrading the API, because packages that use <tt>-Werror</tt> will be broken by the deprecation.<br />
<br />
=== Adding new modules ===<br />
<br />
Adding new modules might cause an unavoidable name collision in dependent code. However, this is usually pretty unlikely, especially if you keep to your own namespace, so only an increase of the minor version number is required. If, however, your added module name is taken from another package (e.g. when <tt>network-bytestring</tt> was merged into <tt>network</tt>) or is quite general (Data.Set or something similar) then the version increase should be major.<br />
<br />
== Dependencies in Cabal ==<br />
<br />
When publishing a Cabal package, you should ensure that your dependencies in the <tt>build-depends</tt> field are accurate. This means specifying not only lower bounds, but also upper bounds on every dependency. <br />
<br />
At some point in the future, Hackage may refuse to accept packages that do not follow this convention. The aim is that before this happens, we will put in place tool support that makes it easier to follow the convention and less painful when dependencies are updated.<br />
<br />
To minimize breakage when new package versions are released, you can use dependencies that are insensitive to minor version changes (e.g. <tt>foo >= 1.2.1 && < 1.3</tt>). However, note that this approach is slightly risky: when a package exports more things than before, there is a chance that your code will fail to compile due to new name-clash errors. The risk from new name clashes may be small, but you are on the safe side if you [[Import modules properly|import identifiers explicitly or using qualification]].<br />
<br />
== Version syntax ==<br />
<br />
Since Cabal 1.6, you can specify an exact API version according to this policy with the special syntax <tt>package == 1.1.4.*</tt> or an API version up to additions with <tt>package == 1.1.*</tt>. The former translates into <tt>package >= 1.1.4 && < 1.1.5</tt>, for example - notice that 1.1.4 ''is'' included, rather than just including 1.1.4.0.<br />
<br />
== Tools ==<br />
<br />
* script to check for API changes in gtk2hs: http://code.haskell.org/gtk2hs/tools/apidiff/<br />
* [http://hackage.haskell.org/package/precis precis] - a simple tool for a first approximation of package API differences, see the [http://www.haskell.org/pipermail/haskell-cafe/2010-April/077023.html announcement]<br />
<br />
== Related ==<br />
<br />
* [[Sven Moritz Hallberg]], "[[The_Monad.Reader/Issue2/EternalCompatibilityInTheory|Eternal compatibility in theory]]," [[The Monad.Reader]], [[The Monad.Reader/Issue2|Issue 2]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=User:Michiexile/MATH198/Lecture_1&diff=46142User:Michiexile/MATH198/Lecture 12012-06-22T02:50:21Z<p>Enoksrd: /* Categories */ Typo.</p>
<hr />
<div>This page now includes additional information based on the notes taken in class. Hopefully this will make the notes reasonably complete for everybody.<br />
<br />
<br />
==Welcome, administratrivia==<br />
<br />
I'm Mikael Vejdemo-Johansson. I can be reached in my office 383-BB, especially during my office hours; or by email to mik@math.stanford.edu.<br />
<br />
I encourage, strongly, student interactions.<br />
<br />
I will be out of town September 24 - 29. I will monitor forum and email closely, and recommend electronic ways of getting in touch with me during this week. I will be back again in time for the office hours on the 30th.<br />
<br />
==Introduction==<br />
===Why this course?===<br />
<br />
An introduction to Haskell will usually come with pointers toward Category Theory as a useful tool, though not with much more than the mention of the subject. This course is intended to fill that gap, and provide an introduction to Category Theory that ties into Haskell and functional programming as a source of examples and applications.<br />
<br />
===What will we cover?=== <br />
<br />
The definition of categories, special objects and morphisms, functors, natural transformation, (co-)limits and special cases of these, adjunctions, freeness and presentations as categorical constructs, monads and Kleisli arrows, recursion with categorical constructs. <br />
<br />
Maybe, just maybe, if we have enough time, we'll finish with looking at the definition of a topos, and how this encodes logic internal to a category. Applications to fuzzy sets.<br />
<br />
===What do we require?===<br />
<br />
Our examples will be drawn from discrete mathematics, logic, Haskell programming and linear algebra. I expect the following concepts to be at least vaguely familiar to anyone taking this course:<br />
* Sets<br />
* Functions<br />
* Permutations<br />
* Groups<br />
* Partially ordered sets<br />
* Vector spaces<br />
* Linear maps<br />
* Matrices<br />
* Homomorphisms<br />
<br />
===Good references===<br />
<br />
On reserve in the mathematics/CS library are:<br />
* ''Mac Lane'': '''Categories for the working mathematician'''<br />
:This book is technical, written for a mathematical audience, and puts in more work than is strictly necessary in many of the definitions. When Awodey and Mac Lane deviate, we will give Awodey priority.<br />
* ''Awodey'': '''Category Theory'''<br />
:This book is also available as an ebook, accessible from the Stanford campus network. The coursework webpage has links to the ebook under Materials.<br />
<br />
===Monoids===<br />
<br />
In order to settle notation and ensure everybody's seen a definition before:<br />
<br />
'''Definition''' A ''monoid'' is a set <math>M</math> equipped with a binary associative operation <math>*</math> (in Haskell: <hask>mappend</hask>) and an identity element <math>\emptyset</math> (in Haskell: <hask>mempty</hask>).<br />
<br />
A ''semigroup'' is a monoid without the requirement for an identity element.<br />
<br />
A function <math>f:M\to N</math> is a monoid homomorphism if the following conditions hold:<br />
* <math>f(\emptyset) = \emptyset</math><br />
* <math>f(m*m') = f(m)*f(m')</math><br />
<br />
'''Examples'''<br />
* Any group is a monoid. Thus, specifically, the integers with addition is a monoid.<br />
* The natural numbers, with addition.<br />
* Strings <math>L^*</math> in an alphabet <math>L</math> is a monoid with string concatenation forming the operation and the empty string the identity.<br />
* Non-empty strings form a semigroup. <br />
<br />
For more information, see the Wikipedia page on Monoids. [[http://en.wikipedia.org/wiki/Monoid]].<br />
<br />
Awodey: p. 10. <br />
<br />
===Partially ordered set===<br />
<br />
'''Definition''' A ''partially ordered set'', or a ''partial order'', or a ''poset'' is a set <math>P</math> equipped with a binary relation <math>\leq</math> which is:<br />
* Reflexive: <math>x\leq x</math> for all <math>x\in P</math><br />
* Anti-symmetric: <math>x\leq y</math> and <math>y\leq x</math> implies <math>x=y</math> for all <math>x,y\in P</math>.<br />
* Transitive: <math>x\leq y</math> and <math>y\leq z</math> implies <math>x\leq z</math> for all <math>x,y,z\in P</math>.<br />
<br />
If <math>x\leq y</math> or <math>y\leq x</math>, we call <math>x,y</math> ''comparable''. Otherwise we call them ''incomparable''. A poset where all elements are mutually comparable is called a ''totally ordered set'' or a ''total order''. <br />
<br />
If we drop the requirement for anti-symmetry, we get a ''pre-ordered set'' or a ''pre-order''.<br />
<br />
If we have several posets, we may indicate which poset we're comparing ''in'' byindicating the poset as a subscript to the relation symbol.<br />
<br />
A ''monotonic'' map of posets is a function <math>f:P\to Q</math> such that <math>x\leq_P y</math> implies <math>f(x)\leq_Q f(y)</math>. <br />
<br />
'''Examples'''<br />
* The reals, natural numbers, integers all are posets with the usual comparison relation. A poset in which all elements are comparable. <br />
* The natural numbers, excluding 0, form a poset with <math>a\leq b</math> if <math>a|b</math>.<br />
* Any family of subsets of a given set form a poset with the order given by inclusion.<br />
<br />
For more information, see the Wikipedia page on Partially ordered set. [[http://en.wikipedia.org/wiki/Partially_ordered_set]]<br />
<br />
Awodey: p. 6. Preorders are defined on page 8-9. <br />
<br />
==Category==<br />
<br />
Awodey has a slightly different exposition. Relevant pages in Awodey for this lecture are: sections 1.1-1.4 (except Def. 1.2), 1.6-1.8. <br />
<br />
===Graphs===<br />
<br />
We recall the definition of a ''(directed) graph''. A graph <math>G</math> is a collection of ''edges (arrows)'' and ''vertices (nodes)''. Each edge is assigned a ''source'' node and a ''target'' node. <br />
<br />
<math>source \to target</math><br />
<br />
Given a graph <math>G</math>, we denote the collection of nodes by <math>G_0</math> and the collection of arrows by <math>G_1</math>. These two collections are connected, and the graph given its structure, by two functions: the source function <math>s:G_1\to G_0</math> and the target function <math>t:G_1\to G_0</math>.<br />
<br />
We shall not, in general, require either of the collections to be a set, but will happily accept larger collections; dealing with set-theoretical paradoxes as and when we have to. A graph where both nodes and arrows are sets shall be called ''small''. A graph where either is a class shall be called ''large''.<br />
0<br />
If both <math>G_0</math> and <math>G_1</math> are finite, the graph is called ''finite'' too.<br />
<br />
The ''empty graph'' has <math>G_0 = G_1 = \emptyset</math>.<br />
<br />
A ''discrete graph'' has <math>G_1=\emptyset</math>.<br />
<br />
A ''complete graph'' has <math>G_1 = \{ (v,w) | v,w\in G_0\}</math>. <br />
<br />
A ''simple graph'' has at most one arrow between each pair of nodes. Any relation on a set can be interpreted as a simple graph.<br />
<br />
* Show some examples.<br />
<br />
A ''homomorphism'' <math>f:G\to H</math> of graphs is a pair of functions <math>f_0:G_0\to H_0</math> and <math>f_1:G_1\to H_1</math> such that sources map to sources and targets map to targets, or in other words:<br />
* <math>s(f_1(e)) = f_0(s(e))</math><br />
* <math>t(f_1(e)) = f_0(t(e))</math><br />
<br />
By a ''path'' in a graph <math>G</math> from the node <math>x</math> to the node <math>y</math> of length <math>k</math>, we mean a sequence of edges <math>(f_1,f_2,\dots,f_k)</math> such that:<br />
* <math>s(f_1)=x</math><br />
* <math>t(f_k)=y</math><br />
* <math>s(f_i) = t(f_{i-1})</math> for all other <math>i</math>.<br />
<br />
Paths with start and end point identical are called ''closed''. For any node <math>x</math>, there is a unique closed path <math>()</math> starting and ending in <math>x</math> of length 0.<br />
<br />
For any edge <math>f</math>, there is a unique path from <math>s(f)</math> to <math>t(f)</math> of length 1: <math>(f)</math>.<br />
<br />
We denote by <math>G_k</math> the set of paths in <math>G</math> of length <math>k</math>. <br />
<br />
===Categories===<br />
<br />
We now are ready to define a category. A ''category'' is a graph <math>G</math> equipped with an associative composition operation <math>\circ:G_2\to G_1</math>, and an identity element for composition <math>1_x</math> for each node <math>x</math> of the graph.<br />
<br />
Note that <math>G_2</math> can be viewed as a subset of <math>G_1\times G_1</math>, the set of all pairs of arrows. It is intentional that we define the composition operator on only a subset of the set of all pairs of arrows - the composable pairs. Whenever you'd want to compose two arrows that don't line up to a path, you'll get nonsense, and so any statement about the composition operator has an implicit "whenever defined" attached to it.<br />
<br />
The definition is not quite done yet - this composition operator, and the identity arrows both have a few rules to fulfill, and before I state these rules, there are some notation we need to cover.<br />
<br />
====Backwards!====<br />
<br />
If we have a path given by the arrows <math>(f,g)</math> in <math>G_2</math>, we expect <math>f:A\to B</math> and <math>g:B\to C</math> to compose to something that goes <math>A\to C</math>. The origin of all these ideas lies in geometry and algebra, and so the abstract arrows in a category are ''supposed'' to behave like functions under function composition, even though we don't say it explicitly.<br />
<br />
Now, we are used to writing function application as <math>f(x)</math> - and possibly, from Haskell, as <hask>f x</hask>. This way, the composition of two functions would read <math>g(f(x))</math>.<br />
<br />
On the other hand, the way we write our paths, we'd read <math>f</math> then <math>g</math>. This juxtaposition makes one of the two ways we write things seem backwards. We can resolve it either by making our paths in the category go backwards, or by reversing how we write function application. <br />
<br />
In the latter case, we'd write <math>x.f</math>, say, for the application of <math>f</math> to <math>x</math>, and then write <math>x.f.g</math> for the composition. It all ends up looking a lot like Reverse Polish Notation, and has its strengths, but feels unnatural to most. It does, however, have the benefit that we can write out function composition as <math>(f,g) \mapsto f.g</math> and have everything still make sense in all notations.<br />
<br />
In the former case, which is the most common in the field, we accept that paths as we read along the arrows and compositions look backwards, and so, if <math>f:A\to B</math> and <math>g:B\to C</math>, we write <math>g\circ f:A\to C</math>, remembering that ''elements'' are introduced from the right, and the functions have to consume the elements in the right order.<br />
<br />
----<br />
<br />
The existence of the identity map can be captured in a function language as well: it is the existence of a function <math>u:G_0\to G_1</math>. <br />
<br />
Now for the remaining rules for composition. Whenever defined, we expect associativity - so that <math>h\circ(g\circ f)=(h\circ g)\circ f</math>. Furthermore, we expect:<br />
# Composition respects sources and targets, so that:<br />
#* <math>s(g\circ f) = s(f)</math><br />
#* <math>t(g\circ f) = t(g)</math><br />
# <math>s(u(x)) = t(u(x)) = x</math><br />
<br />
In a category, arrows are also called ''morphisms'', and nodes are also called ''objects''. This ties in with the algebraic roots of the field.<br />
<br />
We denote by <math>Hom_C(A,B)</math>, or if <math>C</math> is obvious from context, just <math>Hom(A,B)</math>, the set of all arrows from <math>A</math> to <math>B</math>. This is the ''hom-set'' or ''set of morphisms'', and may also be denoted <math>C(A,B)</math>.<br />
<br />
If a category is large or small or finite as a graph, it is called a large/small/finite category.<br />
<br />
A category with objects a collection of sets and morphisms a selection from all possible set-valued functions such that the identity morphism for each object is a morphism, and composition in the category is just composition of functions is called ''concrete''. Concrete categories form a very rich source of examples, though far from all categories are concrete.<br />
<br />
Again, the Wikipedia page on Category (mathematics) [[http://en.wikipedia.org/wiki/Category_%28mathematics%29]] is a good starting point for many things we will be looking at throughout this course.<br />
<br />
===New Categories from old===<br />
<br />
As with most other algebraic objects, one essential part of our tool box is to take known objects and form new examples from them. This allows us generate a wealth of examples from the ones that shape our intuition.<br />
<br />
Typical things to do here would be to talk about ''subobjects'', ''products'' and ''coproducts'', sometimes obvious ''variations on the structure'', and what a ''typical object'' looks like. Remember from linear algebra how ''subspaces'', ''cartesian products'' (which for finite-dimensional vectorspaces covers both products and coproducts) and ''dual spaces'' show up early, as well as the theorems giving ''dimension'' as a complete descriptor of a vectorspace.<br />
<br />
We'll go through the same sequence here; with some significant small variations.<br />
<br />
A category <math>D</math> is a ''subcategory'' of the category <math>C</math> if:<br />
* <math>D_0\subseteq C_0</math><br />
* <math>D_1\subseteq C_1</math><br />
* <math>D_1</math> contains <math>1_X</math> for all <math>X\in D_0</math><br />
* sources and targets of all the arrows in <math>D_1</math> are all in <math>D_0</math><br />
* the composition in <math>D</math> is the restriction of the composition in <math>C</math>.<br />
<br />
Written this way, it does look somewhat obnoxious. It does become easier though, with the realization - studied closer in homework exercise 2 - that the really important part of a category is the collection of arrows. Thus, a subcategory is a subcollection of the collection of arrows - with identities for all objects present, and with at least all objects that the existing arrows imply.<br />
<br />
A subcategory <math>D\subseteq C</math> is ''full'' if <math>D(A,B)=C(A,B)</math> for all objects <math>A,B</math> of <math>D</math>. In other words, a full subcategory is completely determined by the selection of objects in the subcategory.<br />
<br />
A subcategory <math>D\subseteq C</math> is ''wide'' if the collection of objects is the same in both categories. Hence, a wide subcategory picks out a subcollection of the morphisms.<br />
<br />
The ''dual'' of a category is to a large extent inspired by vector space duals. In the dual <math>C^*</math> of a category <math>C</math>, we have the same objects, and the morphisms are given by the equality <math>C^*(A,B)=C(B,A)</math> - every morphism from <math>C</math> is present, but it goes in the ''wrong'' direction. Dualizing has a tendency to add the prefix ''co-'' when it happens, so for instance coproducts are the dual notion to products. We'll return to this construction many times in the course. <br />
<br />
Given two categories <math>C,D</math>, we can combine them in several ways:<br />
# We can form the category that has as objects the disjoint union of all the objects of <math>C</math> and <math>D</math>, and that sets <math>Hom(A,B)=\emptyset</math> whenever <math>A,B</math> come from different original categories. If <math>A,B</math> come from the same original category, we simply take over the homset from that category. This yields a categorical ''coproduct'', and we denote the result by <math>C+D</math>. Composition is inherited from the original categories.<br />
# We can also form the category with objects <math>\langle A,B\rangle</math> for every pair of objects <math>A\in C, B\in D</math>. A morphism in <math>Hom(\langle A,B\rangle,\langle A',B'\rangle)</math> is simply a pair <math>\langle f:A\to A',g:B\to B'\rangle</math>. Composition is defined componentwise. This category is the categorical correspondent to the cartesian ''product'', and we denot it by <math>C\times D</math>.<br />
<br />
In these three constructions - the dual, the product and the coproduct - the arrows in the categories are formal constructions, not functions; even if the original category was given by functions, the result is no longer given by a function.<br />
<br />
Given a category <math>C</math> and an object <math>A</math> of that category, we can form the ''slice category'' <math>C/A</math>. Objects in the slice category are arrows <math>B\to A</math> for some object <math>B</math> in <math>C</math>, and an arrow <math>\phi:f\to g</math> is an arrow <math>s(f)\to s(g)</math> such that <math>f=g\circ\phi</math>. Composites of arrows are just the composites in the base category. <br />
<br />
Notice that the same arrow <math>\phi</math> in the base category <math>C</math> represents potentially many different arrows in <math>C/A</math>: it represents one arrow for each choice of source and target compatible with it.<br />
<br />
There is a dual notion: the ''coslice category'' <math>A\backslash C</math>, where the objects are paired with maps <math>A\to B</math>.<br />
<br />
Slice categories can be used, among other things, to specify the idea of parametrization. The slice category <math>C/A</math> gives a sense to the idea of ''objects from <math>C</math> labeled by elements of <math>A</math>''.<br />
<br />
We get this characterization by interpreting the arrow representing an object as representing its source and a ''type function''. Hence, in a way, the <hask>Typeable</hask> type class in Haskell builds a slice category on an appropriate subcategory of the category of datatypes.<br />
<br />
Alternatively, we can phrase the importance of the arrow in a slice categories of, say, Set, by looking at preimages of the slice functions. That way, an object <math>f:B\to A</math> gives us a family of (disjoint) subsets of <math>B</math> ''indexed'' by the elements of <math>A</math>.<br />
<br />
Finally, any graph yields a category by just filling in the arrows that are missing. The result is called the ''free category generated by the graph'', and is a concept we will return to in some depth. Free objects have a strict categorical definition, and they serve to give a model of thought for the things they are free objects for. Thus, categories are essentially graphs, possibly with restrictions or relations imposed; and monoids are essentially strings in some alphabet, with restrictions or relations.<br />
<br />
===Examples===<br />
<br />
* The empty category.<br />
** No objects, no morphisms.<br />
* The one object/one arrow category <math>1</math>.<br />
** A single object and its identity arrow.<br />
* The categories <math>2</math> and <math>1+1</math>.<br />
** Two objects, <math>A,B</math> with identity arrows and a unique arrow <math>A\to B</math>.<br />
* The category Set of sets.<br />
** Sets for objects, functions for arrows.<br />
* The catgeory FSet of finite sets.<br />
** Finite sets for objects, functions for arrows.<br />
* The category PFn of sets and partial functions.<br />
** Sets for objects. Arrows are pairs <math>(S'\subseteq S,f:S'\to T)\in PFn(S,T)</math>.<br />
** <math>PFn(A,B)</math> is a partially ordered set. <math>(S_f,f)\leq(S_g,g)</math> precisely if <math>S_f\subseteq S_g</math> and <math>f=g|_{S_f}</math>.<br />
** The exposition at Wikipedia uses the construction here: [[http://en.wikipedia.org/wiki/Partial_function]].<br />
* There is an alternative way to define a category of partial functions: For objects, we take sets, and for morphisms <math>S\to T</math>, we take subsets <math>F\subseteq S\times T</math> such that each element in <math>S</math> occurs in at most one pair in the subset. Composition is by an interpretation of these subsets corresponding to the previous description. We'll call this category <math>PFn'</math>.<br />
* Every partial order is a category. Each hom-set has at most one element.<br />
** Objects are the elements of the poset. Arrows are unique, with <math>A\to B</math> precisely if <math>A\leq B</math>.<br />
* Every monoid is a category. Only one object. The elements of the monoid correspond to the endo-arrows of the one object.<br />
* The category of Sets and injective functions.<br />
** Objects are sets. Morphisms are injective functions between the sets.<br />
* The category of Sets and surjective functions.<br />
** Objects are sets. Morphisms are surjective functions between the sets.<br />
* The category of <math>k</math>-vector spaces and linear maps.<br />
* The category with objects the natural numbers and <math>Hom(m,n)</math> the set of <math>m\times n</math>-matrices. <br />
** Composition is given by matrix multiplication.<br />
* The category of Data Types with Computable Functions.<br />
** Our ideal programming language has:<br />
*** Primitive data types.<br />
*** Constants of each primitive type.<br />
*** Operations, given as functions between types. <br />
*** Constructors, producing elements from data types, and producing derived data types and operations.<br />
** We will assume that the language is equipped with<br />
*** A do-nothing operation for each data type. Haskell has <hask>id</hask>.<br />
*** An empty type <math>1</math>, with the property that each type has exactly one function to this type. Haskell has <hask>()</hask>. We will use this to define the constants of type <math>t</math> as functions <math>1\to t</math>. Thus, constants end up being 0-ary functions.<br />
*** A composition constructor, taking an operator <math>f:A\to B</math> and another operator <math>g:B\to C</math> and producing an operator <math>g\circ f:A\to C</math>. Haskell has <hask>(.)</hask>. <br />
** This allows us to model a functional programming language with a category.<br />
* The category with objects logical propositions and arrows proofs.<br />
* The category Rel has objects finite sets and morphisms <math>A\to B</math> being subsets of <math>A\times B</math>. Composition is by <math>(a,c)\in g\circ f</math> if there is some <math>b\in B</math> such that <math>(a,b)\in f, (b,c)\in g</math>. Identity morphism is the diagonal <math>(a,a): a\in A</math>.<br />
<br />
<br />
<br />
<br />
<br />
===Homework===<br />
<br />
For a passing mark, a written, acceptable solution to at least 3 of the 6 questions should be given no later than midnight before the next lecture.<br />
<br />
For each lecture, there will be a few exercises marked with the symbol *. These will be more difficult than the other exercises given, will require significant time and independent study, and will aim to complement the course with material not covered in lectures, but nevertheless interesting for the general philosophy of the lecture course.<br />
<br />
# Prove the general associative law: that for any path, and any bracketing of that path, the same composition results.<br />
# Which of the following form categories? Proof and disproof for each:<br />
#* Objects are finite sets, morphisms are functions such that <math>|f^{-1}(b)|\leq 2</math> for all morphisms f, objects B and elements b.<br />
#* Objects are finite sets, morphisms are functions such that <math>|f^{-1}(b)|\geq 2</math> for all morphisms f, objects B and elements b.<br />
#* Objects are finite sets, morphisms are functions such that <math>|f^{-1}(b)|<\infty</math> for all morphisms f, objects B and elements b.<br />
:Recall that <math>f^{-1}(b)=\{a\in A: f(a)=b\}</math>.<br />
# Suppose <math>u:A\to A</math> in some category <math>C</math>. <br />
## If <math>g\circ u=g</math> for all <math>g:A\to B</math> in the category, then <math>u=1_A</math>.<br />
## If <math>u\circ h=h</math> for all <math>h:B\to A</math> in the category, then <math>u=1_A</math>.<br />
## These two results characterize the objects in a category by the properties of their corresponding identity arrows completely. Specifically, there is a way to rephrase the definition of a category such that everything is stated in terms of arrows.<br />
# For as many of the examples given as you can, prove that they really do form a category. Passing mark is at least 60% of the given examples.<br />
#* Which of the categories are subcategories of which other categories? Which of these are wide? Which are full?<br />
# For this question, all parts are required:<br />
## For which sets is the free monoid on that set commutative.<br />
## Prove that for any category <math>C</math>, the set <math>Hom(A,A)</math> is a monoid under composition for every object <math>A</math>.<br />
:For details on the construction of a free monoid, see the Wikipedia pages on the Free Monoid [[http://en.wikipedia.org/wiki/Free_monoid]] and on the Kleene star [[http://en.wikipedia.org/wiki/Kleene_star]].<br />
# * Read up on <math>\omega</math>-complete partial orders. Suppose <math>S</math> is some set and <math>\mathfrak P</math> is the set of partial functions <math>S\to S</math> - in other words, an element of <math>\mathfrak P</math> is some pair <math>(S_0,f:S_0\to S)</math> with <math>S_0\subseteq S</math>. We give this set a poset structure by <math>(S_0,f)\leq(S_1,g)</math> precisely if <math>S_0\subseteq S_1</math> and <math>f(s)=g(s)\forall s\in S_0</math>.<br />
#* Show that <math>\mathfrak P</math> is a strict <math>\omega</math>-CPO.<br />
#* An element <math>x</math> of <math>S</math> is a ''fixpoint'' of <math>f:S\to S</math> if <math>f(x)=x</math>. Let <math>\mathfrak N</math> be the <math>\omega</math>-CPO of partially defined functions on the natural numbers. We define a function <math>\phi:\mathfrak N\to\mathfrak N</math> by sending some <math>h:\mathbb N\to\mathbb N</math> to a function <math>k</math> defined by<br />
#*# <math>k(0) = 1</math><br />
#*# <math>k(n)</math> is defined only if <math>h(n-1)</math> is defined, and then by <math>k(n)=n*h(n-1)</math>.<br />
:Describe <math>\phi(n\mapsto n^2)</math> and <math>\phi(n\mapsto n^3)</math>. Show that <math>\phi</math> is ''continuous''. Find a fixpoint <math>(S_0,f)</math> of <math>\phi</math> such that any other fixpoint of the same function is larger than this one.<br />
:Find a continuous endofunction on some <math>\omega</math>-CPO that has the fibonacci function <math>F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2)</math> as the least fixed point.<br />
:Implement a Haskell function that finds fixed points in an <math>\omega</math>-CPO. Implement the two fixed points above as Haskell functions - using the <math>\omega</math>-CPO fixed point approach in the implementation. It may well be worth looking at <hask>Data.Map</hask> to provide a Haskell context for a partial function for this part of the task.</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Extensible_record&diff=46133Extensible record2012-06-20T18:54:41Z<p>Enoksrd: /* Papers and libraries */ fix broken link</p>
<hr />
<div>__TOC__<br />
<br />
Proposals, implementations can be found on the [http://hackage.haskell.org/trac/haskell-prime/wiki/FirstClassLabels FirstClassLabels] page of Haskell' Wiki.<br />
<br />
== Papers and libraries ==<br />
* [http://homepages.cwi.nl/~ralf/HList/ HList --- a Haskell library for strongly typed heterogeneous collections] includes also extensible records. Its relatedness to database programming is described in the articles, see also its [http://hackage.haskell.org/trac/summer-of-code/ticket/33 possible] relatedness to [[Libraries and tools/Database interfaces/HaskellDB|HaskellDB]] project.<br />
* Daan Leijen: [http://www.cs.uu.nl/~daan/pubs.html#fclabels First-class labels for extensible rows]. See also the description of the Haskell-like language [http://www.cs.uu.nl/~daan/morrow/ Morrow], it is based on the concepts of the article. And [http://www.cs.uu.nl/~daan/pubs.html#scopedlabels Extensible records with scoped labels]: "We describe a natural approach to typing polymorphic and extensible records that is simple, easy to use in practice, and straightforward to implement."<br />
* Simon Peyton Jones and Greg Morrisett: [http://research.microsoft.com/~simonpj/Haskell/records.html A proposal for records in Haskell]<br />
* Mark Jones and Simon Peyton Jones: [http://research.microsoft.com/~simonpj/Papers/records.htm Lightweight Extensible Records for Haskell]<br />
* Mark P. Jones: [http://www.cs.sfu.ca/CourseCentral/SW/Haskell/hugs/TREX A prototype implementation of extensible records for Hugs]<br />
* Didier Remy's [http://www.cs.uu.nl/wiki/Uhc/ErikKnoop#Typing_record_concatenation_for Typing record concatenation for free] on Erik Knoop's page<br />
* Benedict R. Gaster, Mark P. Jones: [http://web.cecs.pdx.edu/~mpj/pubs/polyrec.html A Polymorphic Type System for Extensible Records and Variants]<br />
* [http://www.comp.nus.edu.sg/~sulzmann/chameleon/ Chameleon], a Haskell-like language, see its [http://www.comp.nus.edu.sg/~sulzmann/chameleon/download/haskell.html#record records] [dead link as of 2011-09-15]<br />
* [[Grapefruit]] contains the package grapefruit-records which implements a record system in Haskell with GHC extensions. This record system allows field selection and dropping of fields using pattern matching. It also supports defaulting.<br />
* [http://www.informatik.tu-cottbus.de/~jeltsch/research/ppdp-2010-paper.pdf Generic Record Combinators with Static Type Checking] describes a record system with several novel features, which is provided by the [http://hackage.haskell.org/package/records records package]. It is derived from the record system of [[Grapefruit]].<br />
* The extensible-data package includes extensible records. <!-- sorry, the CAPTCHA is impossible to read. --><br />
<br />
== Applications ==<br />
<br />
=== Declarative database management ===<br />
<br />
Such systems can achieve more type safety (compared to direct SQL handling).<br />
They usually formulate a [[relational algebra]] concept in a declarative language.<br />
<br />
==== HaskellDB ====<br />
<br />
A problem where some concepts of extensible records could be useful is described in the [[Libraries and tools/Database interfaces/HaskellDB|HaskellDB]] project. More precisely, the problem is described in the paper downloadable from<br />
* [http://haskelldb.sourceforge.net/ Chalmers version of HaskellDB] (see ''Papers'' subsection on [http://haskelldb.sourceforge.net/#documentation Documentation])<br />
* which presupposes reading also paper on the [http://www.haskell.org/haskellDB/ Daan Leijen's original HaskellDB] page (see [http://www.haskell.org/haskellDB/doc.html Documentation subpage], PostScript version)<br />
<br />
[[Libraries and tools/Database interfaces/HaskellDB|HaskellDB]] uses its own extensible record system, but see also [[Libraries and tools/Database interfaces/HaskellDB#Future|HaskellDB#Future]].<br />
<br />
==== CoddFish ====<br />
<br />
[[Libraries and tools/Database interfaces/CoddFish|CoddFish]] is another declarative, type safe database system. As for extensible record system, it uses [http://homepages.cwi.nl/~ralf/HList/ HList --- a Haskell library for strongly typed heterogeneous collections].<br />
<br />
=== Functional Reactive Programming ===<br />
<br />
[[Functional Reactive Programming|FRP]] often makes it necessary to deal with very large tuples as arrow inputs and outputs. For example, a GUI component would receive the behavior of all its writeable properties as its input. Extensible records can therefore make FRP more usable, especially if they provide defaulting.<br />
<br />
==== Grapefruit ====<br />
<br />
[[Grapefruit]] uses extensible records which support pattern matching and defaulting for functional reactive GUI programming.<br />
<br />
== Related concepts ==<br />
<br />
[[Dependent type]] -- as an explanation for its relatedness here, see [http://www.dcs.st-andrews.ac.uk/~james/RESEARCH/ydtm-submitted.pdf Why Dependent Types Matter] written by Thorsten Altenkirch, Conor McBride, James McKinna -- or see at least its ''Conclusions'' section (section 8, pages 18--19).<br />
<br />
[[Type arithmetic]] seems to me also a way yielding some tastes from [[dependent type]] theory.<br />
<br />
[[Relational algebra]] implementations usually use extensible records.<br />
<br />
[[Category:Proposals]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=How_to_write_a_Haskell_program&diff=45843How to write a Haskell program2012-05-31T04:53:29Z<p>Enoksrd: /* Revision control */ Copy edit.</p>
<hr />
<div>A developers' guide to creating a new Haskell project or program, and working in the Haskell developer ecosystem.<br />
<br />
''Note: for learning the Haskell language itself we recommend [http://haskell.org/haskellwiki/Tutorials#Introductions_to_Haskell these resources].''<br />
<br />
== Recommended tools ==<br />
<br />
Almost all new Haskell projects use the following tools. Each is<br />
intrinsically useful, but using a set of common tools also helps<br />
everyone by increasing productivity, and you're more likely to get<br />
patches.<br />
<br />
=== Revision control ===<br />
<br />
Use [http://git-scm.com/ git] or [http://darcs.net darcs] unless you have a specific reason not to. Both are lightweight distributed revision control systems (and darcs is written in Haskell). Both have massive market share in the Haskell world. If you want to encourage contributions from other Haskell hackers then git or darcs are the best. Darcs hosting is available on [http://code.haskell.org code.haskell.org] and [http://patch-tag.com patch-tag]. For git, [http://github.com/ github] is very popular.<br />
<br />
=== Build system ===<br />
<br />
[[Image:Cabal-With-Text-small.png|frame|Built with Cabal]]<br />
<br />
Use [http://haskell.org/cabal/ Cabal].<br />
You should read at least the start of section 2 of the [http://www.haskell.org/cabal/users-guide/ Cabal User's Guide].<br />
<br />
You should use [http://haskell.org/cabal/download.html cabal-install] as a front-end for installing your Cabal library. Cabal-install provides commands not only for building libraries but also for installing them from, and uploading them to, Hackage. As a bonus, for almost all programs, it's faster than using Setup.hs scripts directly, since no time is wasted compiling the scripts. (This does not apply for programs that use custom Setup.hs scripts, since those need to be compiled even when using cabal-install.)<br />
<br />
cabal-install is widely available, as part of the [http://haskell.org/platform Haskell Platform], so you can probably assume your users will have it too.<br />
<br />
=== Documentation ===<br />
<br />
For libraries, use [http://haskell.org/haddock/ Haddock]. We recommend<br />
using the version of Haddock that ships with the Haskell Platform. Haddock generates [http://hackage.haskell.org/packages/archive/base/4.3.1.0/doc/html/Prelude.html nice markup], with links to source.<br />
<br />
=== Testing ===<br />
<br />
You can use [http://hackage.haskell.org/package/QuickCheck QuickCheck] or [http://www.mail-archive.com/haskell@haskell.org/msg19215.html SmallCheck] to test pure code. To test impure code, use [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HUnit HUnit]. See [http://hackage.haskell.org/packages/archive/hashable/1.1.2.2/hashable.cabal this Cabal file] for an example of how to include tests in your Cabal package.<br />
<br />
To get started, try [[Introduction to QuickCheck]]. For a slightly more advanced introduction, [http://blog.codersbase.com/2006/09/simple-unit-testing-in-haskell.html Simple Unit Testing in Haskell] is a blog article about creating a testing framework for QuickCheck using some Template Haskell. For HUnit, see [[HUnit 1.0 User's Guide]]<br />
<br />
=== Distribution ===<br />
<br />
The standard mechanism for distributing Haskell libraries and<br />
applications is [http://hackage.haskell.org/packages/hackage.html Hackage]. Hackage can<br />
host your cabalised tarball releases, and link to any library<br />
dependencies your code has. Users will find and install your packages via "cabal install", and your package will be integrated into Haskell search engines, like [http://www.haskell.org/hoogle/ hoogle]<br />
<br />
=== Target Environment ===<br />
<br />
If at all possible, depend on libraries that are provided by the [http://haskell.org/platform Haskell Platform], and libraries that in turn build against the Haskell Platform. This set of libraries is designed to be widely available, so your end users will be able to build your software.<br />
<br />
== Structure of a simple project ==<br />
<br />
The basic structure of a new Haskell project can be adopted from<br />
[http://semantic.org/hnop/ HNop], the minimal Haskell project. It<br />
consists of the following files, for the mythical project "haq".<br />
<br />
* Haq.hs -- the main haskell source file<br />
* haq.cabal -- the cabal build description<br />
* Setup.hs -- build script itself<br />
* _darcs -- revision control<br />
* README -- info<br />
* LICENSE -- license<br />
<br />
Of course, you can elaborate on this, with subdirectories and multiple<br />
modules. See [[Structure of a Haskell project]] for an example of a larger project's directory structure.<br />
<br />
Here is a transcript that shows how you'd create a minimal darcs and cabalised<br />
Haskell project for the cool new Haskell program "haq", build it,<br />
install it and release.<br />
<br />
''Note'': The new tool "cabal init" automates all this for you, but you should<br />
understand all the parts even so. <br />
<br />
We will now walk through the creation of the infrastructure for a simple<br />
Haskell executable. Advice for libraries follows after.<br />
<br />
=== Create a directory ===<br />
<br />
Create somewhere for the source:<br />
<br />
<code><br />
$ mkdir haq<br />
$ cd haq<br />
</code><br />
<br />
=== Write some Haskell source ===<br />
<br />
Write your program:<br />
<br />
<haskell><br />
$ cat > Haq.hs<br />
--<br />
-- Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/~dons/<br />
-- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html)<br />
--<br />
import System.Environment<br />
<br />
-- | 'main' runs the main program<br />
main :: IO ()<br />
main = getArgs >>= print . haqify . head<br />
<br />
haqify s = "Haq! " ++ s<br />
</haskell><br />
<br />
=== Stick it in version control ===<br />
<br />
Place the source under revision control (you may need to enter your e-mail address first, to identify you as maintainer of this source):<br />
<br />
<code><br />
$ darcs init<br />
$ darcs add Haq.hs <br />
$ darcs record<br />
addfile ./Haq.hs<br />
Shall I record this change? (1/?) [ynWsfqadjkc], or ? for help: y<br />
hunk ./Haq.hs 1<br />
+--<br />
+-- Copyright (c) 2006 Don Stewart - http://www.cse.unsw.edu.au/~dons/<br />
+-- GPL version 2 or later (see http://www.gnu.org/copyleft/gpl.html)<br />
+--<br />
+import System.Environment<br />
+<br />
+-- | 'main' runs the main program<br />
+main :: IO ()<br />
+main = getArgs >>= print . haqify . head<br />
+<br />
+haqify s = "Haq! " ++ s<br />
Shall I record this change? (2/?) [ynWsfqadjkc], or ? for help: y<br />
What is the patch name? Import haq source<br />
Do you want to add a long comment? [yn]n<br />
Finished recording patch 'Import haq source'<br />
</code><br />
<br />
And we can see that darcs is now running the show:<br />
<br />
<code><br />
$ ls<br />
Haq.hs _darcs<br />
</code><br />
<br />
=== Add a build system ===<br />
<br />
Create a .cabal file describing how to build your project:<br />
<br />
<code><br />
$ cat > haq.cabal<br />
Name: haq<br />
Version: 0.0<br />
Description: Super cool mega lambdas<br />
License: GPL<br />
License-file: LICENSE<br />
Author: Don Stewart<br />
Maintainer: dons@cse.unsw.edu.au<br />
Build-Type: Simple<br />
Cabal-Version: >=1.2<br />
<br />
Executable haq<br />
Main-is: Haq.hs<br />
Build-Depends: base >= 3 && < 5<br />
</code><br />
<br />
(If your package uses other packages, e.g. <tt>haskell98</tt>, you'll need to add them to the <tt>Build-Depends:</tt> field as a comma separated list.)<br />
Add a <tt>Setup.hs</tt> that will actually do the building:<br />
<br />
<haskell><br />
$ cat > Setup.hs<br />
import Distribution.Simple<br />
main = defaultMain<br />
</haskell><br />
Cabal allows either <tt>Setup.hs</tt> or <tt>Setup.lhs</tt>.<br />
<br />
Now would also be a good time to add a LICENSE file and a README file. Examples are in the tarball for HNop.<br />
<br />
Record your changes:<br />
<br />
<code><br />
$ darcs add haq.cabal Setup.hs LICENSE README<br />
$ darcs record --all<br />
What is the patch name? Add a build system<br />
Do you want to add a long comment? [yn]n<br />
Finished recording patch 'Add a build system'<br />
</code><br />
<br />
=== Build your project ===<br />
<br />
Now build it! There are two methods of accessing Cabal functionality: through your Setup.hs script or through cabal-install. In most cases, cabal-install is now the preferred method.<br />
<br />
Building using cabal-install:<br />
<br />
<code><br />
$ cabal install --prefix=$HOME --user<br />
</code><br />
<br />
Building using the traditional Setup.hs method:<br />
<br />
<code><br />
$ runhaskell Setup configure --prefix=$HOME --user<br />
$ runhaskell Setup build<br />
$ runhaskell Setup install<br />
</code><br />
<br />
This will install your newly minted haq program in $HOME/bin.<br />
<br />
=== Run it ===<br />
<br />
And now you can run your cool project:<br />
<code><br />
$ haq me<br />
"Haq! me"<br />
</code><br />
<br />
You can also run it in-place, even if you skip the install phase:<br />
<code><br />
$ dist/build/haq/haq you<br />
"Haq! you"<br />
</code><br />
<br />
=== Build some haddock documentation ===<br />
<br />
Generate some API documentation into dist/doc/*<br />
<br />
Using cabal install:<br />
<code><br />
$ cabal haddock<br />
</code><br />
<br />
Traditional method:<br />
<code><br />
$ runhaskell Setup haddock<br />
</code><br />
<br />
which generates files in dist/doc/ including:<br />
<br />
<code><br />
$ w3m -dump dist/doc/html/haq/Main.html<br />
haq Contents Index<br />
Main<br />
<br />
Synopsis<br />
main :: IO ()<br />
<br />
Documentation<br />
<br />
main :: IO ()<br />
main runs the main program<br />
<br />
Produced by Haddock version 0.7<br />
</code><br />
<br />
No output? Make sure you have actually installed haddock. It is a separate program, not something that comes with Cabal. Note that the stylized comment in the source gets picked up by Haddock.<br />
<br />
=== (Optional) Improve your code: HLint ===<br />
<br />
[http://hackage.haskell.org/package/hlint HLint] can be a valuable tool for improving your coding style, particularly if you're new to Haskell. Let's run it now.<br />
<br />
<code><br />
$ hlint .<br />
./Haq.hs:11:1: Warning: Eta reduce<br />
Found:<br />
haqify s = "Haq! " ++ s<br />
Why not:<br />
haqify = ("Haq! " ++)<br />
</code><br />
<br />
The existing code will work, but let's follow that suggestion. Open Haq.hs in your favourite editor and change the line:<br />
<br />
<haskell><br />
where haqify s = "Haq! " ++ s<br />
</haskell><br />
<br />
to:<br />
<br />
<haskell><br />
where haqify = ("Haq! " ++)<br />
</haskell><br />
<br />
=== Add some automated testing: QuickCheck ===<br />
<br />
==== QuickCheck v1 ====<br />
<br />
We'll use QuickCheck to specify a simple property of our Haq.hs code. Create a tests module, Tests.hs, with some QuickCheck boilerplate:<br />
<br />
<haskell><br />
$ cat > Tests.hs<br />
import Char<br />
import List<br />
import Test.QuickCheck<br />
import Text.Printf<br />
<br />
main = mapM_ (\(s,a) -> printf "%-25s: " s >> a) tests<br />
<br />
instance Arbitrary Char where<br />
arbitrary = choose ('\0', '\128')<br />
coarbitrary c = variant (ord c `rem` 4)<br />
</haskell><br />
<br />
Now let's write a simple property:<br />
<br />
<haskell><br />
$ cat >> Tests.hs <br />
-- reversing twice a finite list, is the same as identity<br />
prop_reversereverse s = (reverse . reverse) s == id s<br />
where _ = s :: [Int]<br />
<br />
-- and add this to the tests list<br />
tests = [("reverse.reverse/id", test prop_reversereverse)]<br />
</haskell><br />
<br />
We can now run this test, and have QuickCheck generate the test data:<br />
<br />
<code><br />
$ runhaskell Tests.hs<br />
reverse.reverse/id : OK, passed 100 tests.<br />
</code><br />
<br />
Let's add a test for the 'haqify' function:<br />
<br />
<haskell><br />
-- Dropping the "Haq! " string is the same as identity<br />
prop_haq s = drop (length "Haq! ") (haqify s) == id s<br />
where haqify s = "Haq! " ++ s<br />
<br />
tests = [("reverse.reverse/id", test prop_reversereverse)<br />
,("drop.haq/id", test prop_haq)]<br />
</haskell><br />
<br />
and let's test that:<br />
<br />
<code><br />
$ runhaskell Tests.hs<br />
reverse.reverse/id : OK, passed 100 tests.<br />
drop.haq/id : OK, passed 100 tests.<br />
</code><br />
<br />
Great!<br />
<br />
==== QuickCheck v2 ====<br />
<br />
If you're using version 2 of QuickCheck, the code in the previous section needs some minor modifications:<br />
<br />
<haskell><br />
$ cat > Tests.hs<br />
import Char<br />
import List<br />
import Test.QuickCheck<br />
import Text.Printf<br />
<br />
main = mapM_ (\(s,a) -> printf "%-25s: " s >> a) tests<br />
<br />
-- reversing twice a finite list, is the same as identity<br />
prop_reversereverse s = (reverse . reverse) s == id s<br />
where _ = s :: [Int]<br />
<br />
-- Dropping the "Haq! " string is the same as identity<br />
prop_haq s = drop (length "Haq! ") (haqify s) == id s<br />
where haqify s = "Haq! " ++ s<br />
<br />
tests = [("reverse.reverse/id", quickCheck prop_reversereverse)<br />
,("drop.haq/id", quickCheck prop_haq)]<br />
</haskell><br />
<br />
To run the test:<br />
<br />
<code><br />
$ runhaskell Tests.hs<br />
reverse.reverse/id : +++ OK, passed 100 tests.<br />
drop.haq/id : +++ OK, passed 100 tests.<br />
</code><br />
<br />
Success!<br />
<br />
=== Running the test suite from darcs ===<br />
<br />
We can arrange for darcs to run the test suite on every commit that is run with the flag --test:<br />
<br />
<code><br />
$ darcs setpref test "runhaskell Tests.hs"<br />
Changing value of test from '' to 'runhaskell Tests.hs'<br />
</code><br />
<br />
will run the full set of QuickChecks.<br />
If your test requires it, you may need to ensure other things are built too -- for example:<code>darcs setpref test "alex Tokens.x;happy Grammar.y;runhaskell Tests.hs"</code>.<br />
You will encounter that this way a darcs patch is also accepted if a QuickCheck test fails.<br />
You have two choices to [http://www.haskell.org/pipermail/haskell-cafe/2007-October/033834.html work around] this:<br />
* Use <hask>quickCheck'</hask> from the package QuickCheck-2 and call <hask>exitWithFailure</hask> if it return <hask>False</hask>.<br />
* Keep the test program as it is, and implement the failure on the shell level:<br />
: <code>runhaskell Tests.hs | tee test.log && if grep Falsifiable test.log >/dev/null; then exit 1; fi</code><br />
<br />
Let's commit a new patch:<br />
<br />
<code><br />
$ darcs add Tests.hs<br />
$ darcs record --all --test<br />
What is the patch name? Add testsuite<br />
Do you want to add a long comment? [yn]n<br />
Running test...<br />
reverse.reverse/id : OK, passed 100 tests.<br />
drop.haq/id : OK, passed 100 tests.<br />
Test ran successfully.<br />
Looks like a good patch.<br />
Finished recording patch 'Add testsuite'<br />
</code><br />
<br />
Excellent: now, patches must pass the test suite before they can be committed provided the --test flag is passed.<br />
<br />
=== Tag the stable version, create a tarball, and sell it! ===<br />
<br />
Tag the stable version:<br />
<br />
<code><br />
$ darcs tag<br />
What is the version name? 0.0<br />
Finished tagging patch 'TAG 0.0'<br />
</code><br />
<br />
==== Create a tarball ====<br />
You can do this using either Cabal or darcs, or even an explicit <tt>tar</tt> command.<br />
<br />
===== Using Cabal =====<br />
<br />
Since the code is cabalised, we can create a tarball with cabal-install<br />
directly (you can also use <tt>runhaskell Setup.hs sdist</tt>, but you need <tt>tar</tt> on your system [http://thread.gmane.org/gmane.comp.lang.haskell.cafe/60617/focus=60653]):<br />
<br />
<code><br />
$ cabal sdist<br />
Building source dist for haq-0.0...<br />
Source tarball created: dist/haq-0.0.tar.gz<br />
</code><br />
This has the advantage that Cabal will do a bit more checking, and<br />
ensure that the tarball has the structure that HackageDB expects. <br />
Note that it does require the LICENSE file to exist.<br />
It packages up the files needed to build the project; to include other files (such as <tt>Test.hs</tt> in the above example, and our README), we need to add:<br />
<br />
<code><br />
extra-source-files: Tests.hs README<br />
</code><br />
<br />
to the .cabal file to have everything included.<br />
<br />
===== Using darcs =====<br />
<br />
Alternatively, you can use darcs:<br />
<code><br />
$ darcs dist -d haq-0.0<br />
Created dist as haq-0.0.tar.gz<br />
</code><br />
<br />
And you're all set up!<br />
<br />
==== Check that your source package is complete ====<br />
<br />
Just to make sure everything works, try building the source package in some temporary directory:<br />
<code><br />
$ tar xzf haq-0.0.tar.gz<br />
$ cd haq-0.0<br />
$ cabal configure<br />
$ cabal build<br />
</code><br />
and for packages containing libraries,<br />
<code><br />
$ cabal haddock<br />
</code><br />
<br />
==== Upload your package to Hackage ====<br />
<br />
Whichever of the above methods you've used to create your package, you can upload it to the Hackage package collection via a [http://hackage.haskell.org/packages/upload.html web interface].<br />
You may wish to use the package checking interface there first, and fix things it warns about, before uploading your package.<br />
<br />
=== Summary ===<br />
<br />
The following files were created:<br />
<br />
$ ls<br />
Haq.hs Tests.hs dist haq.cabal<br />
Setup.hs _darcs haq-0.0.tar.gz<br />
<br />
== Libraries ==<br />
<br />
The process for creating a Haskell library is almost identical. The differences<br />
are as follows, for the hypothetical "ltree" library:<br />
<br />
=== Hierarchical source ===<br />
<br />
The source should live under a directory path that fits into the<br />
existing [[Hierarchical module names|module layout guide]].<br />
So we would create the following directory structure, for the module<br />
Data.LTree:<br />
<br />
$ mkdir Data<br />
$ cat > Data/LTree.hs <br />
module Data.LTree where<br />
<br />
So our Data.LTree module lives in Data/LTree.hs<br />
<br />
=== The Cabal file ===<br />
<br />
Cabal files for libraries list the publically visible modules, and have<br />
no executable section:<br />
<br />
$ cat > ltree.cabal <br />
Name: ltree<br />
Version: 0.1<br />
Description: Lambda tree implementation<br />
License: BSD3<br />
License-file: LICENSE<br />
Author: Don Stewart<br />
Maintainer: dons@cse.unsw.edu.au<br />
Build-Type: Simple<br />
Cabal-Version: >=1.2<br />
<br />
Library<br />
Build-Depends: base >= 3 && < 5<br />
Exposed-modules: Data.LTree<br />
ghc-options: -Wall<br />
<br />
We can thus build our library:<br />
<br />
$ cabal configure --prefix=$HOME --user<br />
$ cabal build <br />
Preprocessing library ltree-0.1...<br />
Building ltree-0.1...<br />
[1 of 1] Compiling Data.LTree ( Data/LTree.hs, dist/build/Data/LTree.o )<br />
/usr/bin/ar: creating dist/build/libHSltree-0.1.a<br />
<br />
and our library has been created as a object archive. Now install it:<br />
<br />
$ cabal install<br />
Installing: /home/dons/lib/ltree-0.1/ghc-6.6 & /home/dons/bin ltree-0.1...<br />
Registering ltree-0.1...<br />
Reading package info from ".installed-pkg-config" ... done.<br />
Saving old package config file... done.<br />
Writing new package config file... done.<br />
<br />
And we're done!<br />
To try it out, first make sure that your working directory is anything but the source directory of your library:<br />
<br />
$ cd ..<br />
<br />
And then use your new library from, for example, ghci:<br />
<br />
$ ghci -package ltree<br />
Prelude> :m + Data.LTree<br />
Prelude Data.LTree> <br />
<br />
The new library is in scope, and ready to go.<br />
<br />
=== More complex build systems ===<br />
<br />
For larger projects, you may want to store source trees in subdirectories. This can be done simply by creating a directory -- for example, "src" -- into which you will put your src tree.<br />
<br />
To have Cabal find this code, you add the following line to your Cabal<br />
file:<br />
<br />
hs-source-dirs: src<br />
<br />
You can also set up Cabal to run configure scripts, among other features. For more information consult the<br />
[http://www.haskell.org/cabal/users-guide/ Cabal user guide].<br />
<br />
== Automation ==<br />
<br />
A tool to automatically populate a new cabal project is available:<br />
<br />
cabal init<br />
<br />
Usage is:<br />
<br />
<code><br />
$ cabal init<br />
Package name [default "haq"]? <br />
Package version [default "0.1"]? <br />
Please choose a license:<br />
1) GPL<br />
2) GPL-2<br />
3) GPL-3<br />
4) LGPL<br />
5) LGPL-2.1<br />
6) LGPL-3<br />
* 7) BSD3<br />
8) BSD4<br />
9) MIT<br />
10) PublicDomain<br />
11) AllRightsReserved<br />
12) OtherLicense<br />
13) Other (specify)<br />
Your choice [default "BSD3"]? <br />
Author name? Henry Laxen<br />
Maintainer email? nadine.and.henry@pobox.com<br />
Project homepage/repo URL? http://somewhere.com/haq/<br />
Project synopsis? A wonderful little module<br />
Project category:<br />
1) Codec<br />
2) Concurrency<br />
3) Control<br />
4) Data<br />
5) Database<br />
6) Development<br />
7) Distribution<br />
8) Game<br />
9) Graphics<br />
10) Language<br />
11) Math<br />
12) Network<br />
13) Sound<br />
14) System<br />
15) Testing<br />
16) Text<br />
17) Web<br />
18) Other (specify)<br />
Your choice? 3<br />
What does the package build:<br />
1) Library<br />
2) Executable<br />
Your choice? 1<br />
Generating LICENSE...<br />
Generating Setup.hs...<br />
Generating haq.cabal...<br />
<br />
You may want to edit the .cabal file and add a Description field.<br />
</code><br />
<br />
== Licenses ==<br />
<br />
Code for the common base library package must be BSD licensed. Otherwise, it<br />
is entirely up to you as the author.<br />
Choose a licence (inspired by [http://www.dina.dk/~abraham/rants/license.html this]).<br />
Check the licences of things you use (both other Haskell packages and C<br />
libraries), since these may impose conditions you must follow.<br />
Use the same licence as related projects, where possible. The Haskell community is<br />
split into 2 camps, roughly: those who release everything under BSD, and<br />
(L)GPLers. Some Haskellers recommend avoiding LGPL, due to cross-module optimisation<br />
issues. Like many licensing questions, this advice is controversial. Several Haskell projects<br />
(wxHaskell, HaXml, etc) use the LGPL with an extra permissive clause which gets round the<br />
cross-module optimisation problem.<br />
<br />
== Releases ==<br />
<br />
It's important to release your code as stable, tagged tarballs. Don't<br />
just [http://jackunrue.blogspot.com/2006/11/don-do-releases.html rely on darcs for distribution].<br />
<br />
* '''darcs dist''' generates tarballs directly from a darcs repository<br />
<br />
For example:<br />
<br />
$ cd fps<br />
$ ls <br />
Data LICENSE README Setup.hs TODO _darcs cbits dist fps.cabal tests<br />
$ darcs dist -d fps-0.8<br />
Created dist as fps-0.8.tar.gz<br />
<br />
You can now just post your fps-0.8.tar.gz<br />
<br />
You can also have darcs do the equivalent of 'daily snapshots' for you by using a post-hook.<br />
<br />
put the following in _darcs/prefs/defaults:<br />
apply posthook darcs dist<br />
apply run-posthook<br />
<br />
Advice:<br />
* Tag each release using '''darcs tag'''. For example:<br />
<br />
$ darcs tag 0.8<br />
Finished tagging patch 'TAG 0.8'<br />
<br />
Then people can <tt>darcs pull --partial -t 0.8</tt>, to get just the tagged version (and not the entire history).<br />
<br />
== Hosting ==<br />
<br />
Hosting for repos is available from the Haskell community server:<br />
<br />
http://community.haskell.org/<br />
<br />
A Darcs repository can be published simply by making it available from a<br />
web page.<br />
<br />
== Web page ==<br />
<br />
Create a web page documenting your project! An easy way to do this is to<br />
add a project specific page to [[Haskell|the Haskell wiki]]<br />
<br />
== The user experience ==<br />
<br />
When developing a new Haskell library, it is important to remember how the user expects to be able to build and use a library.<br />
<br />
=== Introductory information and build guide ===<br />
<br />
A typical library user expects to:<br />
<br />
# Visit [[Haskell|Haskell.org]]<br />
# Find the library/program they are looking for:<br />
## if not found, try mailing list; <br />
## if it is hidden, try improving the documentation on haskell.org;<br />
## if it does not exist, try contributing code and documentation) <br />
# Download<br />
# Build and install<br />
# Enjoy<br />
<br />
Each of these steps can pose potential road blocks, and code authors can<br />
do a lot to help code users avoid such blocks. Steps 1..2 may be easy enough, and many coders and users are mainly concerned with step 5. Steps 3..4 are the ones that often get in the way. In particular, the<br />
following questions should have clear answers:<br />
<br />
* Which is the latest version? <br />
* What state is it in? <br />
* What are its aims? <br />
* Where is the documentation?<br />
* Which is the right version for given OS and Haskell implementation?<br />
* How is it packaged, and what tools are needed to get and unpack it?<br />
* How is it installed, and what tools are needed to install it?<br />
* How do we handle dependencies?<br />
* How do we provide/acquire the knowledge and tool-chains needed?<br />
<br />
The best place to answer these questions is a README file,<br />
distributed with the library or application, and often accompanied with<br />
similar text on a more extensive web page.<br />
<br />
=== Tutorials ===<br />
<br />
Generated haddock documentation is usually not enough to help new<br />
programmers learn how to use a library. You must also provide accompanying examples, and even tutorials about the library.<br />
<br />
Please consider providing example code for your library or application. The code should be type-correct and well-commented.<br />
<br />
== Program structure ==<br />
<br />
Monad transformers are very useful for programming in the large,<br />
encapsulating state, and controlling side effects. To learn more about this approach, try [http://www.grabmueller.de/martin/www/pub/Transformers.en.html Monad Transformers Step by Step].<br />
<br />
== Publicity ==<br />
<br />
The best code in the world is meaningless if nobody knows about it. The<br />
process to follow once you've tagged and released your code is:<br />
<br />
=== Join the community ===<br />
<br />
If you haven't already, join the community. The best way to do this is to [http://haskell.org/haskellwiki/Mailing_lists subscribe] to at least haskell-cafe@ and haskell@ mailing lists. Joining the [[IRC_channel|#haskell IRC channel]] is also an excellent idea.<br />
<br />
=== Announce your project on haskell@ ===<br />
<br />
Most important: announce your project releases to the haskell@haskell.org mailing list. Tag your email subject line with "ANNOUNCE: ...". This ensure it will then make it into the [http://haskell.org/haskellwiki/HWN Haskell Weekly News]. To be doubly sure, you can email the release text to the [[HWN|HWN editor]].<br />
<br />
=== Add your code to the public collections ===<br />
<br />
* Add your library or application to the [[Libraries and tools]] page, under the relevant category, so people can find it.<br />
<br />
* If your release is a Cabal package, add it to the [http://hackage.haskell.org/packages/hackage.html Hackage database] (Haskell's CPAN wanna-be).<br />
<br />
=== Blog about it ===<br />
<br />
Blog about it! Blog about your new code on [http://planet.haskell.org Planet Haskell].<br />
Write about your project in your blog, then email the [http://planet.haskell.org/ Planet Haskell] maintainer (ibid on [[IRC channel|#haskell]]) the RSS feed url for your blog<br />
<br />
== Example ==<br />
<br />
[http://cgi.cse.unsw.edu.au/~dons/blog/2006/12/11#release-a-library-today A complete example] of writing, packaging and releasing a new Haskell library under this process has been documented.<br />
<br />
[[Category:Community]]<br />
[[Category:Tutorials]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Leksah&diff=45042Leksah2012-03-29T16:21:54Z<p>Enoksrd: Updated version and date of latest release.</p>
<hr />
<div>[[Image:leksah.png|left|none]]<br />
<br />
'''Leksah: an IDE for Haskell written in Haskell'''<br />
<br />
This is the [http://leksah.org/ Leksah] users' wiki. Leksah is in active development. Version 0.12.0.3 was prereleased 2012/03/11.<br />
<br />
For general information:<br />
<br />
* Visit the [http://leksah.org/ Leksah] website<br />
* Consult the Leksah PDF [http://code.haskell.org/leksah/doc/leksah_manual.pdf manual]<br />
* Check out the [[Leksah FAQ | FAQ]]<br />
* Read the [[Leksah Installation | installation instructions]]<br />
* Contact us for further info (info at leksah.org)<br />
<br />
Leksah Git repositories:<br />
* https://github.com/leksah/leksah <br />
* https://github.com/leksah/leksah-server</div>Enoksrdhttps://wiki.haskell.org/index.php?title=No_import_of_Prelude&diff=42925No import of Prelude2011-11-15T15:26:25Z<p>Enoksrd: /* Answer */ Added newer -X version of command line switch</p>
<hr />
<div>== Question ==<br />
<br />
Is it possible to not load the Prelude when compiling a Haskell module?<br />
<br />
== Answer ==<br />
<br />
You can either do<br />
<br />
<haskell><br />
import Prelude()<br />
</haskell><br />
<br />
or add<br />
<haskell><br />
{-# LANGUAGE NoImplicitPrelude #-}<br />
</haskell><br />
to the top of the module, or equivalently compile with <code>-XNoImplicitPrelude</code> (or older <code>-fno-implicit-prelude</code>) option.<br />
<br />
<hask>import Prelude()</hask> is less aggressive than <code>NoImplicitPrelude</code>.<br />
E.g. with the first method some functions are imported which are silently inserted for several syntactic constructs.<br />
A bare untyped integral number is rewritten as <hask>fromIntegral num</hask><br />
(so its type will be <hask>Num a => a</hask>),<br />
and list generation syntax is rewritten as follows:<br />
<hask>[n..]</hask> <math>\rightarrow</math> <hask>enumFrom</hask>,<br />
<hask>[n..m]</hask> <math>\rightarrow</math> <hask>enumFromTo</hask>,<br />
<hask>[n,o..]</hask> <math>\rightarrow</math> <hask>enumFromThen</hask>,<br />
<hask>[n,o..m]</hask> <math>\rightarrow</math> <hask>enumFromThenTo</hask>.<br />
<br />
There are some such for which even <code>-fno-implicit-prelude</code> isn't enough;<br />
I think these are documented in the "bugs" section of the GHC manual.<br />
<br />
== See also ==<br />
<br />
* Haskell-Cafe: [http://www.haskell.org/pipermail/haskell-cafe/2008-January/037839.html Not to load Prelude]<br />
<br />
[[Category:FAQ]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Haskell_mode_for_Emacs&diff=42466Haskell mode for Emacs2011-10-17T17:07:08Z<p>Enoksrd: /* inferior-haskell-find-definition (C-c M-.) */ Added workaround for C-c M-. not working when .o files are present.</p>
<hr />
<div>haskell-mode is a major mode for Emacs and XEmacs specifically for writing Haskell code. You can get haskell-mode from the web page: http://projects.haskell.org/haskellmode-emacs/ or on Debian you can type <code>apt-get install haskell-mode</code> (although this currently doesn't have the latest version). It is currently maintained by Svein Ove Aas[http://www.mail-archive.com/haskell-cafe@haskell.org/msg66300.html].<br />
<br />
<br />
<br />
<br />
==Development Version==<br />
<br />
<code><br />
$ darcs get http://code.haskell.org/haskellmode-emacs/<br />
</code><br />
<br />
See also [http://trac.haskell.org/haskellmode-emacs/report/1 Active Tickets] in bug tracker.<br />
<br />
==Setup==<br />
<br />
Download and unpack the basic mode and modules into a suitable directory, e.g. <code>~/lib/emacs/haskell-mode/</code> where <code>~</code> stands for your home directory.<br />
<br />
Assuming you have placed the basic mode haskell-mode.el and the modules you want to use in the directory <code>~/lib/emacs/haskell-mode/</code>, add the following command to your init file (<code>~/.emacs</code>):<br />
<br />
<code><br />
(load "~/lib/emacs/haskell-mode/haskell-site-file")<br />
</code><br />
<br />
adding the following lines according to which modules you want to use:<br />
<br />
<code><br />
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)<br />
(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)<br />
;;(add-hook 'haskell-mode-hook 'turn-on-haskell-indent)<br />
;;(add-hook 'haskell-mode-hook 'turn-on-haskell-simple-indent)<br />
</code><br />
<br />
Note that the three indentation modules are mutually exclusive - add at most one. Note that the line of code for simple indentation is commented out (using a preceding ;) in preference for the more advanced indentation module. Installation is now complete!<br />
<br />
==== Inferior Mode ====<br />
<br />
Normally, inf-haskell automatically finds <code>ghci</code> or <code>hugs</code> in your <code>PATH</code>, but if that's not the case (common under Windows), or if you need to specify your preference, just tell Emacs which executable to use with:<br />
<br />
<code><br />
(setq haskell-program-name "/some/where/ghci.exe")<br />
</code><br />
<br />
You can also use <code>cabal-dev ghci</code> inside Emacs:<br />
<br />
<code><br />
(setq haskell-program-name "cabal-dev ghci")<br />
</code><br />
<br />
If you want to use different settings when you use Cygwin Emacs and NTEmacs,<br />
you can test the value of `system-type':<br />
<br />
<code><br />
(setq haskell-program-name<br />
(if (eq system-type 'cygwin)<br />
"/cygdrive/c/ghc/ghc-6.8.1/bin/ghcii.sh"<br />
"c:/ghc/ghc-6.8.1/bin/ghci.exe"))<br />
</code><br />
<br />
Note that Cygwin binaries tend to interact poorly with NTEmacs, especially<br />
w.r.t signal-handling.<br />
<br />
==Tips and use==<br />
Handy keybindings in haskell-mode. See the documentation <code>C-h m</code> for more information:<br />
*<code>C-c C-=</code> inserts an = sign and lines up type signatures and other pattern matches nicely.<br />
*<code>C-c C-|</code> inserts a guard<br />
*<code>C-c C-o</code> inserts a guard <hask>| otherwise =</hask> and lines up existing guards<br />
*<code>C-c C-w</code> inserts a where keyword<br />
*<code>C-c C-.</code> aligns code over a region in a "sensible" fashion.<br />
<br />
Now in version 2.2:<br />
*<code>C-c C-t</code> gets :type for symbol at point, and remembers it<br />
*<code>C-u C-c C-t</code> inserts a type annotation, for symbol at point, on the line above<br />
*<code>C-c C-i</code> gets :info for symbol at point<br />
*<code>C-c M-.</code> find definition of (interpreted) symbol at point<br />
<br />
(See the section below on [[#inf-haskell.el:_the_best_thing_since_the_breadknife|inf-haskell]].)<br />
<br />
Here's an example for <code>C-c C-=</code>. Put your cursor after myInt and hit <code>C-c C-=</code><br />
<haskell><br />
blah :: Int -> Int<br />
blah myInt<br />
</haskell><br />
note how the function signature is reindented to match the column of the = sign.<br />
<haskell><br />
blah :: Int -> Int<br />
blah myInt =<br />
</haskell><br />
<br />
You could also achieve the same effect by selecting the region and typing <code>C-c C-.</code><br />
<br />
You can also use Haskell-Mode to load Emacs buffers with Haskell code in either Hugs or GHC. To load something in Hugs or ghci, type <code>C-c C-l</code> to load the file. Then, you can go on to type <code>C-c C-r</code> (or simply <code>C-c C-l</code> again) to reload the current module when you have made a change.<br />
<br />
=== Indentation ===<br />
Indentation is one thing that nearly all programming modes provide. However, indenting Haskell code is very hard: for a given line, there are nearly always more than column for which indentation makes sense. For example, imagine the following is open in a haskell-mode buffer, where <code>!</code> represents the point:<br />
<br />
<haskell><br />
foo :: Int -> String<br />
foo 0 = f 4 ++ s<br />
where f 4 = "hello" ++ <br />
!<br />
</haskell><br />
<br />
If you ask haskell-mode to indent for you, where should it indent to? There are four basic options:<br />
<br />
<ol><br />
<li><br />
You want to finish off the expression you were writing in the last line. Haskell-mode indents to be underneath the <code>"</code> character at the beginning of <code>"hello"</code>:<br />
<br />
<haskell><br />
where f 4 = "hello" ++<br />
!<br />
</haskell><br />
<br />
This is debatably a bad choice as you'd probably want to indent a bit further in to make it clear that you were carrying on an expression, but the layout rule would accept something like the following:<br />
<br />
<haskell><br />
where f 4 = "hello" ++<br />
"world"<br />
</haskell><br />
<br />
</li><br />
<li><br />
You want to add a second equation for <code>f</code>. Haskell-mode will indent to line up with the first argument, and fill in the <code>f</code> in the equation:<br />
<br />
<haskell><br />
where f 4 = "hello" ++<br />
f !<br />
</haskell><br />
<br />
This is an unlikely choice as the expression in the previous line isn't complete, but haskell-mode isn't smart enough to know that. (If <code>f</code> had been something without arguments, like <hask>where f = "hello"</hask>, then it's impossible to have more than one equation and haskell-mode won't offer this indentation level.)<br />
</li><br />
<li><br />
You want to add a second binding to the <code>where</code>-block. Haskell-mode indents to line up with the <code>f</code>:<br />
<br />
<haskell><br />
where f 4 = "hello" ++<br />
!<br />
</haskell><br />
<br />
</li><br />
<li>You want to start an entirely new top-level binding. Haskell-mode indents to the first column:<br />
<br />
<haskell><br />
foo :: Int -> String<br />
foo 0 = f 4 ++ s<br />
where f 4 = "hello" ++<br />
!<br />
</haskell><br />
<br />
</li><br />
</ol><br />
<br />
These four locations can be reached by repeatedly pressing <code>TAB</code>. This is what's known as the tab-cycle. The innermost location is offered first, then cycling progresses outwards. Although this may seem like an inefficient system (and it is indeed a shame that Haskell's design didn't result in an unambiguous indentation system), you do quickly get used to the tab-cycle and indenting Haskell code.<br />
<br />
==== Do not use indent-region ====<br />
Using indent-region is generally a bad idea on Haskell code, because it would need to know which of the tab-cycle stops you wish to choose for each line. The innermost one is chosen in each case, which often results in unusable code. Moral: just don't use indent-region with haskell-mode.<br />
<br />
==== Using Unicode symbols ====<br />
In Haskell code, you can end up using a lot of mathematical symbols. It is possible to hack the fontifying features of Emacs to change the ASCII textual representations of arrows and operators into the nice-looking real symbols, much like you could with TeX. The following code is a compilation of Emacs lisp code found on the Emacs wiki on the [http://www.emacswiki.org/cgi-bin/wiki/PrettyLambda#toc4 Pretty Lambda] page (that page also has examples of how to apply the general Unicode defuns to other languages):<br />
<br />
HOWEVER: due to the symbols taking up less space, this has the unfortunate side effect of changing the indentation stops that the indent key offers. This will mean that your code may not look properly aligned to those who do not have this feature in their editor, or could even mean that your code means something different to how it looks. (It is possible to contrive an example that looks correct in emacs, but actually fails to compile). The following is left for interest, but probably should NOT be used.<br />
<br />
Haskell-mode has included this feature for a long time now, so you probably just need to <code>(setq haskell-font-lock-symbols t)</code> in your .emacs to use this feature.<br />
<br />
<code><br />
(defun unicode-symbol (name)<br />
"Translate a symbolic name for a Unicode character -- e.g., LEFT-ARROW <br />
or GREATER-THAN into an actual Unicode character code. "<br />
(decode-char 'ucs (case name <br />
(left-arrow 8592)<br />
(up-arrow 8593)<br />
(right-arrow 8594)<br />
(down-arrow 8595) <br />
(double-vertical-bar #X2551) <br />
(equal #X003d)<br />
(not-equal #X2260)<br />
(identical #X2261)<br />
(not-identical #X2262)<br />
(less-than #X003c)<br />
(greater-than #X003e)<br />
(less-than-or-equal-to #X2264)<br />
(greater-than-or-equal-to #X2265) <br />
(logical-and #X2227)<br />
(logical-or #X2228)<br />
(logical-neg #X00AC) <br />
('nil #X2205)<br />
(horizontal-ellipsis #X2026)<br />
(double-exclamation #X203C)<br />
(prime #X2032)<br />
(double-prime #X2033)<br />
(for-all #X2200)<br />
(there-exists #X2203)<br />
(element-of #X2208) <br />
(square-root #X221A)<br />
(squared #X00B2)<br />
(cubed #X00B3) <br />
(lambda #X03BB)<br />
(alpha #X03B1)<br />
(beta #X03B2)<br />
(gamma #X03B3)<br />
(delta #X03B4))))<br />
<br />
(defun substitute-pattern-with-unicode (pattern symbol)<br />
"Add a font lock hook to replace the matched part of PATTERN with the <br />
Unicode symbol SYMBOL looked up with UNICODE-SYMBOL."<br />
(font-lock-add-keywords<br />
nil `((,pattern <br />
(0 (progn (compose-region (match-beginning 1) (match-end 1)<br />
,(unicode-symbol symbol)<br />
'decompose-region)<br />
nil))))))<br />
<br />
(defun substitute-patterns-with-unicode (patterns)<br />
"Call SUBSTITUTE-PATTERN-WITH-UNICODE repeatedly."<br />
(mapcar #'(lambda (x)<br />
(substitute-pattern-with-unicode (car x)<br />
(cdr x)))<br />
patterns))<br />
<br />
(defun haskell-unicode ()<br />
(substitute-patterns-with-unicode<br />
(list (cons "\\(<-\\)" 'left-arrow)<br />
(cons "\\(->\\)" 'right-arrow)<br />
(cons "\\(==\\)" 'identical)<br />
(cons "\\(/=\\)" 'not-identical)<br />
(cons "\\(()\\)" 'nil)<br />
(cons "\\<\\(sqrt\\)\\>" 'square-root)<br />
(cons "\\(&&\\)" 'logical-and)<br />
(cons "\\(||\\)" 'logical-or)<br />
(cons "\\<\\(not\\)\\>" 'logical-neg)<br />
(cons "\\(>\\)\\[^=\\]" 'greater-than)<br />
(cons "\\(<\\)\\[^=\\]" 'less-than)<br />
(cons "\\(>=\\)" 'greater-than-or-equal-to)<br />
(cons "\\(<=\\)" 'less-than-or-equal-to)<br />
(cons "\\<\\(alpha\\)\\>" 'alpha)<br />
(cons "\\<\\(beta\\)\\>" 'beta)<br />
(cons "\\<\\(gamma\\)\\>" 'gamma)<br />
(cons "\\<\\(delta\\)\\>" 'delta)<br />
(cons "\\(<nowiki>''</nowiki>\\)" 'double-prime)<br />
(cons "\\('\\)" 'prime)<br />
(cons "\\(!!\\)" 'double-exclamation)<br />
(cons "\\(\\.\\.\\)" 'horizontal-ellipsis))))<br />
<br />
(add-hook 'haskell-mode-hook 'haskell-unicode)</code><br />
<br />
== Bugs ==<br />
Bugs and feature requests should be sent to the maintainer [mailto:svein.ove@aas.no Svein Ove Aas].<br />
For people using the Debian package, Debian maintains a [http://bugs.debian.org/cgi-bin/pkgreport.cgi?pkg=haskell-mode list of bugs] for haskell-mode, they should be reported there.<br />
<br />
===XEmacs===<br />
On some the GNU/Linux systems with XEmacs, admittedly, only verified on Ubuntu and Debian and with haskell-mode 2.2, there is a system function missing that interferes with automatic indenting. Secondly, there seems to be an issue with setting the <code-lisp>haskell-default-face</code-lisp> to <code-lisp>nil</code-lisp>.<br />
<br />
====line-end-position====<br />
<br />
To fix this, find where the haskell mode package is installed on your system. (Usually <code>/usr/share/emacs/site-lisp/haskell-mode</code>). Edit the file <code>haskell-indent.el</code> and add the lines:<br />
<pre-lisp><br />
(eval-and-compile<br />
<br />
;; If `line-end-position' isn't available provide one.<br />
(unless (fboundp 'line-end-position)<br />
(defun line-end-position (&optional n)<br />
"Return the `point' of the end of the current line."<br />
(save-excursion<br />
(end-of-line n)<br />
(point)))))<br />
</pre-lisp><br />
right after the comments at the top. That should fix the issue.<br />
<br />
====haskell-default-face====<br />
<br />
This one shows up when typing in code (at various spots - most often when typing a qualified function, such as <hask>List.map</hask>.)<br />
<br />
To fix this one, edit the file <code>haskell-font-lock.el</code>. Look for the line that says:<br />
<pre-lisp><br />
(defvar haskell-default-face nil)<br />
</pre-lisp><br />
and change this to <br />
<pre-lisp><br />
(defvar haskell-default-face 'default)<br />
</pre-lisp><br />
In my version, this is line 168.<br />
<br />
Then, look for the line that says:<br />
<pre-lisp><br />
(,qvarid 0 haskell-default-face)<br />
</pre-lisp><br />
and change it to<br />
<pre-lisp><br />
(,qvarid 0 (symbol-value 'haskell-default-face))<br />
</pre-lisp><br />
<br />
For me, this is line 326 of the file.<br />
YMMV - hope this helps.<br />
<br />
<!--<br />
=== GNU Emacs ===<br />
<br />
==== ghci buffer infested with "^J"s, C-c C-t doesn't work ====<br />
<br />
(only happens after loading a haskell file into ghci)<br />
<br />
--><br />
<br />
<br />
== inf-haskell.el: the best thing since the breadknife ==<br />
inf-haskell.el is _awesome_. At one point I decided to sit down and write a list of functions I'd love to have in haskell-mode, intending to write them myself. I thought I'd check to see whether the key shortcuts I'd chosen were free but I was surprised to find that ''every one'' of these functions is already provided by inf-haskell.el! Here's a selection of the highlights:<br />
<br />
=== Getting set up ===<br />
inf-haskell.el is usually already setup as part of the haskell-mode package, so there is nothing special to do for it. On some systems, you may need this in your .emacs:<br />
<br />
<pre-lisp><br />
(require 'inf-haskell)<br />
</pre-lisp><br />
<br />
To use the following functions, first find a .hs file, then hit C-c C-l (inferior-haskell-load-file). This fires up Hugs or Ghci (you can change this by customising haskell-program-name) on your file. Don't worry if it's not an isolated module, GHCi will load all the modules it imports as normal. You can even load entire programs this way by using C-c C-l on the Main.hs file. If everything loads without errors, you'll be able to use the functions below.<br />
<br />
=== inferior-haskell-type (C-c C-t) ===<br />
Say you have the following code:<br />
<br />
foo = foldr (+) 0 [1..20]<br />
<br />
Perhaps you've forgotten the order of arguments to foldr. It's easily done; I can never remember whether the operation or final value comes first. That's easy to check: just put your point between the 'f' and 'r' of 'foldr' and hit C-c C-t RET. The type of foldr will be revealed in the echo area. This isn't particularly impressive; haskell-doc.el already did this. However, this will work for ''any'' function in the module in question ''or'' in those modules imported by the current module (including the standard libs)!<br />
<br />
If you find that the type shown in the echo area is overwritten after a short amount of time (or any other such problem, of course), please report it as a bug. We know of no such bug, but someone apparently bumped into some such problem which he says he worked around by disabling doc-mode and decl-scan:<br />
<br />
To turn off haskell-doc-mode, add the following to your .emacs:<br />
<pre-lisp><br />
(remove-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)<br />
</pre-lisp><br />
To turn off haskell-decl-scan, just refrain from turning it on (it's not enabled by default).<br />
<br />
(P.S. I re-use haskell-doc-mode to save queried type info, and re-display it in the minibuffer. Disabling doc mode would disable that. -- mrd)<br />
<br />
Another nice feature of this function is the ability to automatically insert type signatures for the function at point on the line above. For example, suppose you have the below open in Emacs, with the point represented by -!-:<br />
<br />
-!-map _ [] = []<br />
map f (x:xs) = f x : map f xs<br />
<br />
And press C-u C-c C-t (note the prefix argument), it will result in the following:<br />
<br />
map :: (a -> b) -> [a] -> [b]<br />
-!-map _ [] = []<br />
map f (x:xs) = f x : map f xs<br />
<br />
=== inferior-haskell-info (C-c C-i) ===<br />
The :info command in GHCi/Hugs is extremely useful; it'll tell you:<br />
<br />
* The definition of an algebraic datatype given its name. E.g. try <code>:info Bool</code>. The output will contain something like <code>data Bool = True | False</code>.<br />
* The classes a type instantiates given the type's name. <code>:info Bool</code> will also give you the classes Bool instantiates. If you can't see an instance you think should be there, make sure the module where that instance is declared is loaded.<br />
* The type of a function, given its name.<br />
* The types of the methods of a class, and the number of arguments of that class, given the class name.<br />
* The expansion of a type synonym given that synonym's name.<br />
<br />
And for all of the above, :info will also tell you the filename and line where that thing is defined. inferior-haskell-info lets you hook into this power. Use it with C-c C-i on anything within a Haskell file.<br />
<br />
=== inferior-haskell-find-definition (C-c M-.) ===<br />
This one needs little explanation. Sometimes you just need to find the source of a function, or datatype, or class, or type synonym etc. to see how it works, and this function lets you do just that. Unfortunately, it won't work on the standard lib modules or anything that isn't 'local' to your project. This is one of the most useful functions inf-haskell.el provides.<br />
<br />
It only works on interpreted code, for which GHCi has location information. In particular, if you have compiled versions of your files (.o and .hi) laying around then GHCi will load those, instead of interpreting your .hs files, which breaks <code>C-c M-.</code>. This seems like a bug, but there is an easy workaround: when compiling your code, send the .hi and .o files to somewhere GHCi won't find them. This has the added benefit of keeping your source dir cleaner. E.g. <code>ghc -odir tmp -hidir tmp --make Main.hs</code>. <br />
<br />
If you want a more general find-definition, use hasktags to create a TAGS file and then use the normal emacs <code>M-.</code> with that. -- mrd<br />
: Note that you can also create a TAGS file using GHCi's :etags command. [[User:DavidHouse|DavidHouse]] 14:38, 29 April 2007 (UTC)<br />
<br />
: Again, :etags/:ctags only works for interpreted code.<br />
<br />
: <code>inferior-haskell-mode</code> is missing TAB completion, which in GHCi works basically for everything (GHCi commands, modules, functions, language extensions, file names etc.). -- Oleksandr Manzyuk<br />
<br />
== Tricks and tweaks ==<br />
<br />
=== Automatic unit testing ===<br />
Here's a cute trick I've evolved:<br />
<br />
I'm a great fan of [[unit test first]], as described by eXtremeProgramming on TheOriginalWiki.<br />
<br />
With the code below, I can press F12 and immediately run all of my unit tests, and immediately see whether they all passed or not.<br />
I've put all of my unit tests into their own file with a main function that runs the tests and gives an exitcode according to the test results. I've specified that the compile-command for that file compiles and runs the file.<br />
<br />
This elisp code will run the <code>compile</code> command from the F12 key in emacs. The output will popup a new window twelve lines tall. If the compilation is successful (exitcode zero) the window goes away. If the exitcode is 1 or greater, the window stays so you can see the output.<br />
<pre-lisp><br />
(require 'compile)<br />
<br />
;; this means hitting the compile button always saves the buffer<br />
;; having to separately hit C-x C-s is a waste of time<br />
(setq mode-compile-always-save-buffer-p t)<br />
;; make the compile window stick at 12 lines tall<br />
(setq compilation-window-height 12)<br />
<br />
;; from enberg on #emacs<br />
;; if the compilation has a zero exit code, <br />
;; the windows disappears after two seconds<br />
;; otherwise it stays<br />
(setq compilation-finish-function<br />
(lambda (buf str)<br />
(unless (string-match "exited abnormally" str)<br />
;;no errors, make the compilation window go away in a few seconds<br />
(run-at-time<br />
"2 sec" nil 'delete-windows-on<br />
(get-buffer-create "*compilation*"))<br />
(message "No Compilation Errors!"))))<br />
<br />
<br />
;; one-button testing, tada!<br />
(global-set-key [f12] 'compile)<br />
</pre-lisp><br />
<br />
<br />
This Haskell code has some Emacs local variable settings at the bottom specifying what the compile-command should be for this buffer.<br />
<haskell><br />
import HUnit<br />
import System<br />
<br />
myTestList = <br />
TestList [<br />
"add numbers" ~: 5 ~=? (3 + 2)<br />
,"add numbers" ~: 5 ~=? (3 + 3)<br />
]<br />
<br />
h = runTestTT myTestList<br />
<br />
main = do c <- h<br />
putStr $ show c<br />
let errs = errors c<br />
fails = failures c<br />
System.exitWith (codeGet errs fails)<br />
<br />
codeGet errs fails<br />
| fails > 0 = ExitFailure 2<br />
| errs > 0 = ExitFailure 1<br />
| otherwise = ExitSuccess<br />
<br />
-- Local Variables:<br />
-- compile-command: "ghc --make -o Test_Demo -i/home/shae/src/haskell/libraries/ HUnitDemo.hs && ./Test_Demo"<br />
-- End:<br />
</haskell><br />
<br />
<br />
If you have any questions, ideas, or suggestions for this code, the maintainer would love to hear them.<br />
<br />
=== Hoogle integration ===<br />
From haskell-mode version 2.4 onwards, the built-in function haskell-hoogle will hoogle the identifier at point.<br />
<br />
=== Using rectangular region commands ===<br />
<br />
Emacs has a set of commands which operate on the region as if it were rectangular. This turns out to be extremely useful when dealing with whitespace sensitive languages.<br />
<br />
<code>C-x r o</code> is "Open Rectangle". It will shift any text within the rectangle to the right side. Also see:<br />
<br />
<code>C-x r t</code> is "String Rectangle". It will shift any text within the rectangle over to the right, and insert a given string prefixing all the lines in the region. If comment-region didn't already exist, you could use this instead, for example.<br />
<br />
<code>C-x r d</code> is "Delete Rectangle". It will delete the contents of the rectangle and move anything on the right over.<br />
<br />
<code>C-x r r</code> is "Copy Rectangle to Register". It will prompt you for a register number so it can save it for later.<br />
<br />
<code>C-x r g</code> is "Insert register". This will insert the contents of the given register, overwriting whatever happens to be within the target rectangle. (So make room)<br />
<br />
<code>C-x r k</code> is "Kill rectangle". Delete rectangle and save contents for:<br />
<br />
<code>C-x r y</code> is "Yank rectangle". This will insert the contents of<br />
the last killed rectangle.<br />
<br />
As with all Emacs modifier combos, you can type <code>C-x r C-h</code> to find out what keys are bound beginning with the <code>C-x r</code> prefix.<br />
<br />
=== Aligning code ===<br />
<br />
Emacs22 has a neat tool called: align-regexp. Select a region you want to align text within, M-x align-regexp, and type a regexp representing the alignment delimiter.<br />
<br />
For example, I often line up my Haddock comments:<br />
<br />
<haskell><br />
f :: a -- ^ does a<br />
-> Foo b -- ^ and b<br />
-> c -- ^ to c<br />
</haskell><br />
<br />
Select the region, and let the regexp be: <code>--</code><br />
<br />
<haskell><br />
f :: a -- ^ does a<br />
-> Foo b -- ^ and b<br />
-> c -- ^ to c<br />
</haskell><br />
<br />
Of course, this works for just about anything. Personally, I've globally bound it to <code>C-x a r</code>:<br />
<br />
<code>(global-set-key (kbd "C-x a r") 'align-regexp)</code>.<br />
<br />
=== Automatically building ===<br />
Emacs 21 has a package that can be installed (included by default in 22 and up) called 'FlyMake'; the idea is that as you are editing away, it occasionally calls the interpreter/compiler automatically and keeps track of whether the code works or not. You can fairly easily get it to work for Haskell as well; see [http://www.emacswiki.org/cgi-bin/wiki/FlymakeHaskell FlymakeHaskell] on the Emacs wiki.<br />
<br />
=== Emacs Integration with Hayoo ===<br />
<br />
My newly installed system would not allow me to hoogle what I wanted (no xmonad or xmonadcontrib in hoogle) so someone suggested Hayoo.<br />
<br />
<code><br />
(define-key haskell-mode-map (kbd "<f3>")<br />
(lambda ()<br />
(interactive)<br />
(browse-url (format "http://holumbus.fh-wedel.de/hayoo/hayoo.html?query=%s&start"<br />
(region-or-word-at-point)))))<br />
</code><br />
<br />
region-or-word-at-point is available in the thing-at-pt+.el library.<br />
<br />
Added 22-12-2008 - Promt for hayoo word<br />
<br />
<code><br />
(defun rgr/hayoo()<br />
(interactive)<br />
(let* ((default (region-or-word-at-point))<br />
(term (read-string (format "Hayoo for the following phrase (%s): "<br />
default))))<br />
(let ((term (if (zerop (length term)) default term)))<br />
(browse-url (format "http://holumbus.fh-wedel.de/hayoo/hayoo.html?query=%s&start" term)))))<br />
<br />
<br />
(define-key haskell-mode-map (kbd "<f3>") 'rgr/hayoo)<br />
</code><br />
<br />
Alternatively use the excellent browse-apropos-url stuff:<br />
<br />
http://www.emacswiki.org/emacs/BrowseAproposURL#toc6<br />
<br />
[http://richardriley.net Richard]<br />
<br />
Note: Using and URL like this should work too and will give better results (not yet tested as I'm not an emacs user):<br />
<br />
<code><br />
http://holumbus.fh-wedel.de/hayoo/hayoo.html?query=%s<br />
</code><br />
<br />
[[User:Tbh|Tbh]] 00:56, 25 January 2009 (UTC)<br />
<br />
=== Integration with HLint ===<br />
<br />
[http://www-users.cs.york.ac.uk/~ndm/hlint/ HLint] could be used directly from Emacs buffer. There is [http://www.cs.york.ac.uk/fp/darcs/hlint/data/hs-lint.el hs-lint.el] package (in HLint distribution, in the data subdirectory), that allows user to run HLint and navigate through errors, or apply suggestions to the source code.<br />
<br />
This package implements `hs-lint` command, that behaves differently depending on settings. If the `hs-lint-replace-with-suggestions` variable is set to `t`, then it will ask user and apply concrete suggested change to source code, otherwise you'll be able to navigate through list of suggestions with `next-error` command. If the `hs-lint-replace-without-ask` variable is also set to `t`, then all suggestions will applied automatically. <br />
<br />
You can also bind `hs-lint` command to some key (in this example this is `C-c l`) with following code:<br />
<br />
<code><br />
(defun my-haskell-mode-hook ()<br />
(local-set-key "\C-cl" 'hs-lint))<br />
(add-hook 'haskell-mode-hook 'my-haskell-mode-hook)<br />
</code><br />
<br />
All settings, described above are available for customization via `hs-lint` customization group.<br />
<br />
[[Category:Development tools]]<br />
<br />
=== Folding ===<br />
For folding parts of code you can use<br />
*'''hide-show.el'''<br />
*and '''hs-outline-level''' (based on py-outline-level created by Gb)<br />
<br />
<code><br />
;; this gets called by outline to determine the level. Just use the length of the whitespace<br />
(defun hsk-outline-level ()<br />
(let (buffer-invisibility-spec)<br />
(save-excursion<br />
(skip-chars-forward "\t ")<br />
(current-column))))<br />
<br />
;; this get called after haskell mode is enabled <br />
(add-hook<br />
'haskell-mode-hook<br />
(lambda ()<br />
;; outline uses this regexp to find headers. I match lines with no indent and indented<br />
;; some lines, such as "--" ... "class"<br />
(setq outline-regexp "^[^\t ].*\\|^.*[\t ]+\\(where\\|of\\|do\\|in\\|if\\|then\\|else\\|let\\|module\\|import\\|deriving\\|instance\\|class\\)[\t\n ]")<br />
;; enable our level computation<br />
(setq outline-level 'hsk-outline-level)<br />
;; do not use their \C-c@ prefix, too hard to type. Note this overides some python mode bindings<br />
;;(setq outline-minor-mode-prefix "C-c")<br />
;; turn on outline mode<br />
(outline-minor-mode t)<br />
;; initially hide all but the headers<br />
;;(hide-body)<br />
))<br />
</code><br />
<br />
*Also, you can use '''toggle-selective-display''' for global folding<br />
<br />
<code><br />
;; folding for all rows, starting on the current column<br />
(defun toggle-selective-display (column)<br />
(interactive "P")<br />
(set-selective-display<br />
(or column<br />
(unless selective-display<br />
(1+ (current-column))))))<br />
<br />
(global-set-key (kbd "C-x $") 'toggle-selective-display)<br />
<br />
(defun toggle-hiding (column)<br />
(interactive "P")<br />
(if hs-minor-mode<br />
(if (condition-case nil<br />
(hs-toggle-hiding)<br />
(error t))<br />
(hs-show-all))<br />
(toggle-selective-display column)))<br />
<br />
(global-set-key (kbd "C-@") 'toggle-hiding)<br />
</code><br />
<br />
*and '''narrowing capabilities''' for folding the rest of code<br />
<code><br />
(put 'narrow-to-defun 'disabled nil)<br />
(put 'narrow-to-page 'disabled nil)<br />
(put 'narrow-to-region 'disabled nil)<br />
</code><br />
<br />
*or '''folding-mode''', if you do not mind add markers such as '''{-{{{-}''' and '''{-}}}-}''' in code.<br />
<br />
=== Speedbar ===<br />
<br />
Emacs has a [http://www.emacswiki.org/emacs/SpeedBar SpeedBar] which works quite nice together with haskell-mode and also detects syntactic elements such as variables, imports, instances, classes.<br />
<br />
Just add<br />
<code><br />
(require 'speedbar)<br />
(speedbar-add-supported-extension ".hs")<br />
</code><br />
to your .emacs file and fire up speedbar with <code>M-x speedbar</code>.<br />
<br />
=== Literate Haskell ===<br />
<br />
Literate Haskell is supported directly by haskell-mode without having to use MMM or other tricks that may be found in old mailing list postings, so ignore that out of date information. If you load an .lhs file, then literate haskell should automatically work. If it doesn't then you should make sure that you are using a current version of haskell-mode and that the correct literate type is selected. You can switch between bird (the default) and tex by typing:<br />
<br />
<code><br />
M-x customize-variable RET haskell-literate-default<br />
</code><br />
<br />
=== Keeping Imports sorted and aligned ===<br />
<br />
See this [http://www.youtube.com/watch?v=UXHSiUPKLvg&fmt=35 screencast about making imports automatically alphabetically ordered and indented].<br />
<br />
The extension modules for that can be found at https://github.com/chrisdone/haskell-mode-exts#readme<br />
<br />
=== Scion Integration ===<br />
<br />
The [http://code.google.com/p/scion-lib/ Scion IDE library] can be used to complement the haskell-mode with additional features, such as (quoting the documentation):<br />
<br />
* Highlights error messages directly in the source, together with a tool-tip<br />
* Optional on-the-fly typechecking (idle-time based, or whenever file is saved)<br />
* Completion on `LANGUAGE` names, pragmas, external module names and `OPTIONS`-flags<br />
* Go to definition sites of symbols at point<br />
<br />
Documentation on how to use `scion.el` can be found in the `README.markdown` file.<br />
<br />
The primary repository is at [https://github.com/nominolo/scion nominolo/scion]. An experimental fork featuring GHC7 support can be found at [https://github.com/hvr/scion hvr/scion]. The hackage version is probably outdated, so better use the upstream version.<br />
<br />
=== HSnippets, YASnippet snippets ===<br />
<br />
[http://code.google.com/p/yasnippet/ YASnippet] is a template system for Emacs. It allows you to type an abbreviation and automatically expand it into function templates.<br />
<br />
[https://github.com/polypus74/HSnippets HSnippets] is designed for use with haskell-indentation-mode, i.e. it does not do any indentation itself, but relies on the mode (or the user) to do so. Also note that the snippets never add any unnecessary lines to the code listing, only the lines taken up by the snippet itself, leaving the user to manage empty space themselves...</div>Enoksrdhttps://wiki.haskell.org/index.php?title=Xmonad/Frequently_asked_questions&diff=39258Xmonad/Frequently asked questions2011-03-29T21:31:43Z<p>Enoksrd: /* xmonad does not detect my multi-head setup */ Added parenthetical showing how to get ./config output from cabal install</p>
<hr />
<div>{{xmonad}}<br />
<br />
''xmonad: frequently asked questions''<br />
<br />
''For configuration tricks, and using xmonad.hs, see [[Xmonad/General_xmonad.hs_config_tips]]''.<br />
<br />
''For more documentation, see'':<br />
<br />
* [http://xmonad.org/intro.html Building xmonad]<br />
* [http://xmonad.org/contrib.html Configuring and extending xmonad]<br />
* [http://xmonad.org/xmonad-docs/xmonad-contrib/ Extension documentation]<br />
<br />
==When I start xmonad, nothing happens.==<br />
<br />
Don't panic, this is expected behavior. XMonad is a minimal window manager, meaning it doesn't set a background, start a status bar, display a splash screen or play a soothing sound effect when it starts up. Once xmonad has started, the only thing it does is listen for your first command. Try pressing mod-shift-enter (that is Alt, Shift, and Enter pressed at the same time) to bring up an xterm. Once the xterm appears, use it to read xmonad's man page or point a web browser at http://xmonad.org/tour.html. If no xterm appears, see if any other advice on this page applies.<br />
<br />
==Installation==<br />
<br />
===What build dependencies does xmonad have?===<br />
<br />
The [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmonad hackage page for xmonad] lists all dependencies, including:<br />
<br />
* Standard Haskell libraries (you might already have these installed):<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Cabal Cabal]<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/mtl mtl]<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/unix unix]<br />
<br />
* Haskell X11 bindings:<br />
** [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/X11 X11]<br />
<br />
* C libraries:<br />
** libX<br />
** libXext<br />
** libXinerama<br />
<br />
You likely have these already if you've built any programs for X.<br />
<br />
xmonad is also availble pre-packaged for many distributions:<br />
<br />
* [http://www.openbsd.org/cgi-bin/cvsweb/ports/x11/xmonad/ OpenBSD]<br />
* [http://pkgsrc.se/wip/xmonad NetBSD]<br />
* [http://www.freshports.org/x11-wm/xmonad/ FreeBSD]<br />
* [http://packages.gentoo.org/package/xmonad Gentoo]<br />
* [http://packages.debian.org/sid/xmonad Debian]<br />
* [http://packages.ubuntu.com/hardy/xmonad Ubuntu]<br />
* [http://aur.archlinux.org/packages.php?do_Details=1&ID=10593 Arch]<br />
* [http://loupgaroublond.blogspot.com/2007/12/how-to-install-your-very-own-xmonad.html Fedora]<br />
* [http://recipes.gobolinux.org/r/?list=XMonad Gobo]<br />
* [http://nix.cs.uu.nl/nixos/ NixOS]<br />
* [http://codex.sourcemage.org/stable/windowmanagers/xmonad/ Source Mage]<br />
* [http://code.haskell.org/~arossato/xmonad-slack/ Slackware]<br />
<br />
Using your distro package is almost always preferred.<br />
<br />
===Can I install without root permission?===<br />
<br />
Yes, the Haskell libraries that xmonad depends on can all by<br />
installed in the user package database. Simply append --user <br />
to the install phase:<br />
<br />
$ runhaskell Setup.hs install --user<br />
<br />
The library will be registered in your ~/.ghc/ database.<br />
<br />
===How can I use xmonad with a display manager? (xdm, kdm, gdm)===<br />
<br />
The simplest way is to create or modify your ~/.xsession file to run<br />
xmonad. If you don't already have a .xsession, the minimal example<br />
looks like:<br />
<br />
xmonad<br />
<br />
This requires that the ghc and the xmonad executable (or a symlink to them) are in a<br />
directory in the display manager $PATH environment. Alternatively, you can use the full path to xmonad and set ghc's path systemwide. If you do this, you'll also have to change the mod-q binding to use /path/to/xmonad and restart X to have xmonad use the new mod-q (first time only) since the mod-q binding calls xmonad to recompile itself. (See mod-q doesn't work section below.)<br />
<br />
People using 'startx' can use these example [http://code.haskell.org/XMonadContrib/scripts/xinitrc xinitrc] and [http://code.haskell.org/XMonadContrib/scripts/run-xmonad.sh run-xmonad] scripts.<br />
<br />
If you are using xdm, you're done. Login and enjoy xmonad.<br />
<br />
If you're using kdm or gdm (KDE and GNOME's display mangers, respectively),<br />
you're almost done. When logging in, select the entry that says "xsession"<br />
or "default session" from the menu in order to use your ~/.xsession to<br />
start xmonad.<br />
<br />
Alternatively, if you want a menu entry specifically for xmonad, create a<br />
file named "xmonad.desktop" in your /usr/share/xsessions (location varies<br />
by distribution) directory. For example:<br />
<br />
[Desktop Entry]<br />
Encoding=UTF-8<br />
Name=xmonad<br />
Comment=This session starts xmonad<br />
Exec=/usr/local/bin/xmonad<br />
Type=Application<br />
<br />
Replace the "Exec=..." line with the actual path to your xmonad executable,<br />
and you should be able to login by selecting "xmonad" as a session from the<br />
menu in gdm/kdm.<br />
<br />
For instructions on using gdm to launch a full GNOME session with xmonad as<br />
the window manager<br />
[http://haskell.org/haskellwiki/Xmonad/Using_xmonad_in_Gnome#Starting_GNOME_with_xmonad read this].<br />
<br />
===Compiling xmonad on PowerPC and compiler is not interactive===<br />
<br />
If you have ghc installed and are trying to compile xmonad and your compiler <br />
complains about not being interactive, never fear. To compile Setup.hs simply type:<br />
<br />
ghc --make Setup.hs -o Setup<br />
<br />
Now you can:<br />
<br />
./Setup configure<br />
./Setup build<br />
sudo ./Setup install<br />
<br />
If during the build process ghc complains about the "impossible<br />
happening", and mentions that you should change something to "-fvia-C",<br />
just edit the *.cabal file replacing the line that sets the arguments<br />
for ghc, changing "-fasm" to "-fvia-C".<br />
<br />
=== How do I uninstall xmonad? ===<br />
<br />
If you have installed xmonad using your package manager, then just use it.<br />
The following applies if you have built xmonad from source code (either darcs or stable release). Let's assume you've installed xmonad to <br />
<br />
the <code>$PREFIX</code> (that is, gave <code>--prefix=$PREFIX</code> argument to <code>Setup.lhs configure</code>). If unsure, try your <br />
<br />
<code>$HOME</code> and <code>/usr/local</code> as <code>$PREFIX</code>.<br />
<br />
rm -f $PREFIX/bin/xmonad<br />
rm -rf $HOME/.xmonad<br />
rm -rf $PREFIX/lib/xmonad-$VERSION<br />
# If you have installed XMonadContrib:<br />
rm -rf $PREFIX/lib/xmonad-contrib-$VERSION<br />
<br />
If you have installed xmonad 0.5 or newer, also run<br />
ghc-pkg unregister xmonad<br />
# If you have installed XMonadContrib:<br />
ghc-pkg unregister xmonad-contrib<br />
<br />
Do not forget to purge that evil source code!<br />
<br />
=== not found errors or changes to xmonad.hs won't take effect ===<br />
<br />
Ensure that ghc, and the xmonad executable are both in the environment PATH from which you start X. Alternatively symlink them to locations already in the PATH. <code>ghc-pkg list</code> should show ghc, xmonad, X11, etc. without brackets, e.g. {xmonad} is bad. <code>ghc-pkg check</code> will tell you if you have inconsistent dependencies or other registration problems.<br />
<br />
The mod-q action calls the xmonad binary to recompile itself, so if your display manager is starting it with /path/to/xmonad you'll also have to edit your xmonad.hs mod-q binding to use the full path and restart X (or in newer versions use 'xmonad --restart') to restart xmonad with the new mod-q full path binding.<br />
<br />
'''If you recently changed ghc versions''' see [[#Upgraded GHC and now xmonad xmonad-contrib etc are not found]]<br />
<br />
===Configuring xmonad requires GHC, which is 200MB!===<br />
<br />
Yes. You can use [http://braincrater.wordpress.com/2008/09/17/xmonad-light-08-released/ xmonad-light], which allows some of the basic configurations, but if you really want to get the best xmonad experience, you need GHC.<br />
<br />
==Configuration==<br />
<br />
===How do I configure xmonad?===<br />
<br />
By creating and editing the ~/.xmonad/xmonad.hs file, a Haskell source file.<br />
<br />
You can use any Haskell you want in this module. The xmonad-contrib package contains many [http://xmonad.org/xmonad-docs/xmonad-contrib/ extension modules] to make customizing xmonad easier. To have your changes take effect, save the xmonad.hs and either restart (mod-q) or exit X and log back in.<br />
<br />
[[Xmonad/Config_archive|Example configurations]] are available on the wiki.<br />
<br />
For extensive information on configuring, see the links at the top of this page, and [http://haskell.org/haskellwiki/Xmonad/General_xmonad.hs_config_tips the configuration tips] page.<br />
<br />
===Rebinding the mod key (Alt conflicts with other apps; I want the ___ key!)===<br />
<br />
xmonad uses 'alt', actually mod1, as the default modifier. You may<br />
bind to other mod keys by editing your xmonad.hs modMask value, or by<br />
using xmodmap to rebind a key to mod1. The apple command key can be<br />
rebound to mod1 in this way. Use xmodmap to find what key your mod1<br />
is bound to, as well.<br />
<br />
You can rebind the Caps Lock key, to mod, if you wish. See this<br />
[http://lists.suckless.org/dwm/0706/2715.html mailing list item].<br />
<br />
If your new key binding doesn't appear to work, double check it doesn't<br />
clash with an existing binding.<br />
<br />
An example, binding to the mod4 (often 'Win') key:<br />
<br />
<haskell><br />
import XMonad<br />
<br />
main = xmonad defaultConfig<br />
{ modMask = mod4Mask<br />
, terminal = "urxvt"<br />
}<br />
</haskell><br />
<br />
===Multi head and workspaces (desktops)===<br />
See also [[#Multi_head_or_xinerama_troubles|xinerama troubles]] if your multi-head setup doesn't behave as described below.<br />
<br />
XMonad's defaults may seem confusing and chaotic until explained and illustrated. First we'll look at how things work by default, then at the most common keybinding customizations people make.<br />
<br />
To ''focus'' visible workspaces rather than ''swapping'' their screens modify your keybindings as shown in [[#Replacing greedyView with view|the next section below]]. See the section about [[#Other multi head customizations|other customizations]] to give each monitor its own set of workspaces.<br />
<br />
The xmonad man page nicely summarizes how multi-head works by default:<br />
<blockquote>When running with multiple monitors (Xinerama, TwinView, xrandr), each screen has exactly 1 workspace visible. Pressing '''<code>mod-{w,e,r}</code>''' switches the focus between screens, while pressing '''<code>shift-mod-{w,e,r}</code>''' moves the current window to that screen. When xmonad starts, workspace 1 is on screen 1, workspace 2 is on screen 2, etc. When switching workspaces to one that is already visible, the current and visible workspaces are swapped.</blockquote><br />
<br />
'''visible workspaces swap''' (default keybindings): When you have multiple workspaces visible and mod-n to a different ''visible'' workspace, your current one swaps with the other one. We'll see how to change that below, if you don't like the swapping -- simply change 'greedyView' to 'view' in your workspace key bindings. To illustrate with two monitors, using the convention "[1*] [3 ]" to mean workspaces 1 and 3 are visible with left monitor the currently active one:<br />
<br />
<code><br />
-- 'greedyView' (default) workspace switching (easier to swap visible workspaces)<br />
<br />
-- Typical keystrokes are mod-{w,e,r} to a screen, then mod-N a workspace<br />
<br />
[1*] [3 ] -- mod-3 --> [3*] [1 ] -- mod-e, mod-4 --> [3 ] [4*]<br />
<br />
[3 ] [4*] -- mod-w, mod-4 --> [4*] [3 ]<br />
</code><br />
<br />
'''my focus moves instead''' (custom workspace switching bindings): By replacing the 'greedyView' function with 'view' in the workspace switching bindings you can have your focus shift to the monitor displaying the given workspace, instead of having that workspace 'brought to you.' (See the next section for examples of how to do this.) For example:<br />
<br />
<code><br />
-- 'view' workspace switching <br />
<br />
-- (easier to focus another visible workspace, harder to swap)<br />
<br />
[1*] [3 ] -- mod-3 --> [1 ] [3*] -- mod-4 --> [1 ] [4*]<br />
<br />
[1 ] [4*] -- mod-w --> [1*] [4 ] -- mod-4 --> [1 ] [4*]<br />
</code><br />
<br />
Users of the <hask>view</hask> action may also want to add key bindings such<br />
as shiftNextScreen and swapNextScreen from the contrib extension<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-CycleWS.html Actions.CycleWS]<br />
<br />
====Replacing greedyView with view====<br />
Here is an example of changing your workspace switching bindings to use <hask>view</hask> rather than <hask>greedyView</hask> '''using XMonad.Util.EZConfig's additionalKeysP:''' <br />
<br />
(See [http://hackage.haskell.org/package/xmonad-contrib contrib docs] for EZConfig for more details)<br />
<br />
<haskell><br />
import XMonad<br />
-- skipped<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Util.EZConfig<br />
<br />
main = do<br />
xmonad $ defaultConfig {<br />
workspaces = myWorkspaces<br />
-- skipped<br />
} `additionalKeysP` myKeys<br />
<br />
myWorkspaces = ["one","two","three","foo","bar","baz","lambda","no","more"]<br />
<br />
myKeys =<br />
[<br />
-- other additional keys<br />
]<br />
++ -- important since ff. is a list itself, can't just put inside above list<br />
[ (otherModMasks ++ "M-" ++ [key], action tag)<br />
| (tag, key) <- zip myWorkspaces "123456789"<br />
, (otherModMasks, action) <- [ ("", windows . W.view) -- was W.greedyView<br />
, ("S-", windows . W.shift)]<br />
]<br />
</haskell><br />
<br />
'''For use with additionalKeys or default binding style:'''<br />
<br />
<haskell><br />
-- as above<br />
myKeys =<br />
[<br />
-- other additional keys<br />
]<br />
++<br />
[((m .|. mod4Mask, k), windows $ f i)<br />
| (i, k) <- zip myWorkspaces [xK_1 .. xK_9]<br />
, (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]<br />
</haskell><br />
<br />
====Other multi head customizations====<br />
By default, XMonad doesn't link all your monitor screens into one workspace like Gnome and friends, neither does it use a model like dwm's where each monitor has its own set of workspaces. To set up dwm style workspaces for each screen, see (0.9 or greater) [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-IndependentScreens.html Layout.IndependentScreens]<br />
<br />
==== Screens are in wrong order ====<br />
With xmonad-contrib newer than 0.8.*, (darcs version), see also<br />
[http://haskell.org/haskellwiki/Xmonad/Notable_changes_since_0.8 XMonad.Actions.PhysicalScreens]<br />
<br />
Sometimes drivers don't do what you want, and your screens left to right are something<br />
weird like 1 0 2, so your mod-{w,e,r} bindings are messed up. Your driver may provide a utility to set screen order, but if not, or if you just don't want to mess with<br />
it, here's how to rebind the screen switching bindings:<br />
<br />
Note that if you choose not to use myKeys for the key lists appended together with <hask>++</hask> you will need to add parentheses to get something in the form <hask>`additionalKeys` ( [......] ++ [.......] )</hask>.<br />
<br />
'''Using XMonad.Util.EZConfig's additionalKeysP:'''<br />
<haskell><br />
import XMonad<br />
-- skipped<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Util.EZConfig<br />
<br />
main = do<br />
xmonad $ defaultConfig {<br />
-- skipped<br />
} `additionalKeysP` myKeys<br />
<br />
modm = mod4Mask<br />
<br />
myKeys =<br />
[<br />
-- other additional keys<br />
]<br />
++<br />
[ (mask ++ "M-" ++ [key], screenWorkspace scr >>= flip whenJust (windows . action))<br />
| (key, scr) <- zip "wer" [1,0,2] -- was [0..] *** change to match your screen order ***<br />
, (action, mask) <- [ (W.view, "") , (W.shift, "S-")]<br />
]<br />
</haskell><br />
<br />
'''Using default key binding method or XMonad.Util.EZConfig's additionalKeys:'''<br />
<haskell><br />
-- as above<br />
myKeys =<br />
[<br />
-- other additional keys<br />
]<br />
++<br />
[((m .|. modm, key), screenWorkspace sc >>= flip whenJust (windows . f))<br />
| (key, sc) <- zip [xK_w, xK_e, xK_r] [1,0,2] -- was [0..] *** change to match your screen order ***<br />
, (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]<br />
</haskell><br />
<br />
===I don't want the focus to follow the mouse===<br />
<br />
Easy. There is a setting focusFollowsMouse in the xmonad.hs file; set it to False and restart with mod+q.<br />
<br />
=== How do I configure pointer-follows-focus? ===<br />
If you are using > xmonad-0.7, you can use the already defined XMonad.Actions.UpdatePointer:<br />
<haskell><br />
myLogHook = dynamicLogWithPP .... >> updatePointer<br />
</haskell><br />
<br />
For xmonad-0.7, in your config, import [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-Warp.html XMonad.Actions.Warp] from Xmonad contrib and <br />
<br />
add this function:<br />
<haskell><br />
pointerFollowsFocus :: Rational -> Rational -> X ()<br />
pointerFollowsFocus h v = do<br />
dpy <- asks display<br />
root <- asks theRoot<br />
withFocused $ \w -> do<br />
wa <- io $ getWindowAttributes dpy w<br />
(sameRoot,_,w',_,_,_,_,_) <- io $ queryPointer dpy root<br />
if (sameRoot && w == w') then<br />
return ()<br />
else<br />
io $ warpPointer dpy none w 0 0 0 0<br />
(fraction h (wa_width wa)) (fraction v (wa_height wa))<br />
where fraction x y = floor (x * fromIntegral y)</haskell><br />
<br />
Then set the logHook in your config to &ldquo;pointerFollowsFocus <i>x</i> <i>y</i>&rdquo;. If you already have a logHook, append &ldquo; <br />
<br />
>> pointerFollowsFocus <i>x</i> <i>y</i>&rdquo; to it. For example:<br />
<haskell>myLogHook = dynamicLogWithPP defaultPP { ppCurrent = xmobarColor "#60ff45" ""<br />
, ppVisible = xmobarColor "#fffff0" "" } >> pointerFollowsFocus 1 1</haskell><br />
<br />
===Does xmonad support a statusbar?===<br />
<br />
Yes. The Hooks.DynamicLog and Hooks.ManageDocks modules are your friends for this purpose. <br />
<br />
Arbitrary external programs may be used as a statusbar. See for example<br />
[http://gotmor.googlepages.com/dzen dzen] or<br />
[http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xmobar xmobar], an<br />
extensible status bar.<br />
<br />
xmonad lets you use any application as a 'statusbar', as long as it is<br />
visible in a given 'gap' on the screen, and has the override-redirect<br />
property set to true. Many status bar/dock programs already set this<br />
property, for example, dzen. To set other applications, you can<br />
sometimes use normal X resources. For example, to use xclock, launch it<br />
with <br />
<br />
xclock -digital -xrm '*overrideRedirect: True' -geometry 1024x30+0+0<br />
<br />
'''If, like xclock, your app doesn't set wm strut properties''', so that ManageDocks and avoidStruts automatically leaves a gap, '''you can do it manually. Import the Layout.Gaps module and, set a gap of, e.g. (30,0,0,0), in xmonad.hs.''' A similar trick can be done for xsystray.<br />
<br />
Also see the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-Monitor.html Layout.Monitor] module.<br />
<br />
You can see screenshots of statusbars on [[Xmonad/Screenshots|the screenshots page]].<br />
<br />
You can also use [http://haskell.org/haskellwiki/Xmonad/Using_xmonad_in_Gnome Gnome] or KDE trays and menus with xmonad. The [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-EwmhDesktops.html Hooks.EwmhDesktops], [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Desktop.html Config.Desktop], [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Gnome.html Config.Gnome], [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Config-Kde.html Config.Kde], etc. modules make desktop environment status bars more useful with xmonad.<br />
<br />
To display xmonad logHook output in gnome-panel, see [http://uhsure.com/xmonad-log-applet.html xmonad log applet].<br />
<br />
==== dzen status bars ==== <br />
<br />
xmonad's XMonadContrib library comes with a<br />
really easy function for getting a status bar working with dzen. To use<br />
it, simply have a ~/.xmonad/xmonad.hs containing:<br />
<haskell><br />
import XMonad<br />
import XMonad.Hooks.DynamicLog<br />
<br />
-- 0.9 main:<br />
main = xmonad =<< dzen defaultConfig<br />
-- 0.8.1 main:<br />
main = dzen xmonad<br />
</haskell><br />
which will launch xmonad with dzen2 if found, set up with nice colours<br />
and workspace information. See [[Xmonad/Config_archive/Don%27s_xmonad.hs|Don's config example]] for more information or [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html#v%3Adzen DynamicLog dzen's] documentation.<br />
<br />
There is an excellent command-line option and in-text command reference for the SVN version of dzen2 [http://dzen.geekmode.org/dwiki/doku.php?id=dzen:command-and-option-list here]<br />
<br />
====gkrellm or other monitors that aren't bars====<br />
<br />
Gkrellm does not behave like a dock by default. However, there is an option in <code>.gkrellm2/user_config</code> which says <code>dock = 0</code>. If you set it to 1 xmonad will recognize gkrellm as a dock. <br />
<br />
Unfortunately gkrellm usually won't hide under other windows regardless of any combination of <code>above</code> and <code>below</code> options in said config file. Opening and closing the gkrellm config usually resolves this (right click the top of gkrellm and select Configure.. from the menu).<br />
<br />
In xmonad-darcs (will release as xmonad-0.9) the Layout.Monitor module may be helpful.<br />
<br />
====Make space for a panel dock or tray====<br />
<br />
[http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageDocks.html ManageDocks] makes it possible for Xmonad to work with panels in the way they expect, automatically leaving the appropriate amount of room for them at the edges of the screen. ''ManageDocks'' has been enabled in the example configuration above. By itself, configuration looks like this:<br />
<br />
<haskell><br />
import XMonad<br />
import XMonad.Hooks.ManageDocks<br />
main = xmonad defaultConfig<br />
{ manageHook = manageDocks <+> manageHook defaultConfig<br />
, layoutHook = avoidStruts $ layoutHook defaultConfig<br />
}<br />
</haskell><br />
<br />
=== Make new windows appear 'below' rather than 'above' the current window ===<br />
See also the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-InsertPosition.html Hooks.InsertPosition] module for placement hooks other than W.SwapDown to use in stack order manageHooks.<br />
<br />
==== Force a few tiled windows down ====<br />
If you only need to position a few windows below rather than above, and can specify window properties that will avoid matching floating dialogs, etc. then adding a few swapDown manageHooks (or similar from Hooks.InsertPosition referenced above) should do the trick.<br />
<br />
<haskell><br />
import XMonad<br />
import qualified XMonad.StackSet as W<br />
main = xmonad defaultConfig<br />
{ manageHook = composeAll<br />
[ resource =? "downer" --> doF W.swapDown<br />
, title =? "obnoxious window" --> doF W.swapDown<br />
, className =? "MPlayer" --> doFloat<br />
]<br />
}<br />
</haskell><br />
<br />
==== Limit windows forced down by using composeOne ====<br />
To position as many windows as possible below the focus while avoiding problems with z-order while using multiple floating windows, use [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageHelpers.html Hooks.ManageHelpers] composeOne and (-?>) in place of composeAll and (-->) to specify hooks that only fire if earlier ones have not matched. You can use this to add swapDown last in your composeOne list, so that it's applied only to windows that haven't earlier been floated or identified as transient or dialog windows.<br />
<br />
<haskell><br />
import XMonad<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Hooks.ManageDocks (checkDock)<br />
import XMonad.Hooks.ManageHelpers<br />
<br />
main = xmonad defaultConfig<br />
-- no gimp or mplayer windows will get swapped down<br />
-- since they matched earlier in the composeOne list<br />
{ manageHook = composeOne<br />
[ checkDock -?> doIgnore -- equivalent to manageDocks<br />
, className =? "Gimp" -?> doFloat<br />
, className =? "MPlayer" -?> doFloat<br />
, return True -?> doF W.swapDown<br />
]<br />
}<br />
</haskell><br />
<br />
For a more complex composeOne example, see [http://mauke.ath.cx/stuff/xmonad/xmonad.hs mauke's manageHooks].<br />
<br />
==== Force all new windows down ====<br />
(Not recommended) Add <hask>doF W.swapDown</hask> to your manageHook. For instance, a minimal config would look like this:<br />
<br />
<haskell><br />
import XMonad<br />
import qualified XMonad.StackSet as W<br />
main = xmonad defaultConfig<br />
{ manageHook = manageHook defaultConfig <+> doF W.swapDown<br />
-- <br />
-- To prevent unwanted swaps on other workspaces when using<br />
-- this hook with other doShift hooks, make sure to put<br />
-- doF W.swapDown furthest to the right, or last in a <br />
-- composeAll hook list<br />
}<br />
</haskell><br />
<br />
'''Warning:''' <code>doF W.swapDown</code> without restrictions will result in new floating windows popping up ''behind'' focused floating windows, and undesirable focus changes when starting and quickly destroying a window. Better would be to only match specific windows to swapDown or use composeOne as shown above.<br />
<br />
==== Avoid the master window, but otherwise manage new windows normally ====<br />
Note that this is not a good solution for people who use floating windows, since many operations on floats put the floating window into the master position. Some transient windows will be swappedDown to appear below the floating parent unless the user keeps a tiled window in master and floating windows lower in the stack at all times. As with swapDown it's best to use it only on specific windows or at the end of a composeOne list if you use floating windows very often.<br />
<br />
<haskell><br />
-- <snip> <br />
import qualified XMonad.StackSet as W<br />
import XMonad.Hooks.ManageHelpers<br />
-- <snip><br />
<br />
myManageHook = fmap not isDialog --> doF avoidMaster<br />
<br />
-- or if you have other stuff in the managehook, more like<br />
-- myManageHook = (otherStuff) <+> (fmap not isDialog --> doF avoidMaster)<br />
<br />
avoidMaster :: W.StackSet i l a s sd -> W.StackSet i l a s sd<br />
avoidMaster = W.modify' $ \c -> case c of<br />
W.Stack t [] (r:rs) -> W.Stack t [r] rs<br />
otherwise -> c<br />
</haskell><br />
<br />
=== Prevent new windows from stealing focus ===<br />
Use a <hask>doF W.focusDown</hask> manageHook on selected windows, or even<br />
on all windows, similar to the swapDown examples above.<br />
<br />
For an avoidMaster that keeps the focus with the master instead of focusing<br />
the newly created window replace <hask>W.Stack t [] (r:rs) -> W.Stack t [r] rs</hask><br />
with <hask>W.Stack t [] (r:rs) -> W.Stack r [] (t:rs)</hask> in the above avoidMaster code.<br />
<br />
===Firefox annoyances===<br />
<br />
====Stop Firefox from taking focus while using EwmhDesktops====<br />
If one uses EWM Hints support, firefox is enabled to choose when you view its workspace, i.e. if you open links from emails or irc or whatever. If you find it annoying... In about:config (vimperator :preferences!) set <code>browser.tabs.loadDivertedInBackground</code> to True to be able to load urls while working elsewhere, then browse them all later when ''you'' choose to shift to the firefox workspace. Also ubuntu users may need to disable the <code>ubufox</code> extension.<br />
<br />
====Firefox's annoying popup downloader====<br />
<br />
Some applications, notably Firefox 1 and 2, create tranisent windows not<br />
set with the transient property. (e.g. firefox's download manager). When<br />
these windows appear, they can take focus and be annoying. For the case<br />
of firefox, the 'Download Statusbar' extension is useful for disabling<br />
this annoying UI feature.<br />
<br />
=== Watch fullscreen flash video ===<br />
For browser plugins and most apps, including mplayer floated by manage hook (as in the default manageHook) the following setup allows normal toggling of fullscreen. A few mplayer versions are configured to use a different fullscreen method, but they can be made to work with the isFullscreen hook by adding a line <code>fstype=none</code> to ~/.mplayer/config, or using the <code>-fstype=none</code> flag from the command line. See also the end of the faq regarding using handleEventHook instead.<br />
<br />
Add one of the following manageHooks, and modify layoutHook with smartBorders:<br />
<haskell><br />
-- other imports<br />
import qualified XMonad.StackSet as W<br />
import XMonad.Hooks.ManageHelpers<br />
import XMonad.Layout.NoBorders<br />
<br />
main = xmonad defaultConfig {<br />
-- skipped<br />
, layoutHook = smartBorders (yourExistingLayoutHook) -- Don't put borders on fullFloatWindows<br />
, manageHook = myManageHooks<br />
}<br />
<br />
myManageHooks = composeAll<br />
-- Allows focusing other monitors without killing the fullscreen<br />
-- [ isFullscreen --> (doF W.focusDown <+> doFullFloat)<br />
<br />
-- Single monitor setups, or if the previous hook doesn't work<br />
[ isFullscreen --> doFullFloat<br />
-- skipped<br />
]<br />
</haskell><br />
If you have multi-head and the focusDown hook doesn't work for you, in darcs xmonad/xmonad-contrib (greater than 0.9.1) XMonad.Hooks.EwmhDesktops has a fullscreenEventHook that is also worth a try. Add it to any existing handleEventHook with <+>, or simply use it as your handleEventHook if you don't already have one. This also is useful for people who prefer tiling mplayer when not fullscreened, or use totem, vlc, or other players that require something like fullscreenEventHook to work at all.<br />
<br />
=== Floating a window or sending it to a specific workspace by default ===<br />
<br />
See [[Xmonad/General_xmonad.hs_config_tips | General xmonad.hs config tips]] regarding manageHook, and the section [[#I need to find the class title or some other X property of my program | here]] about 'xprop' for this.<br />
<br />
===Startup programs===<br />
<br />
You may launch programs at startup in the usual X manner: by adding<br />
them to your .xsession or .Xinitrc. For example, the following<br />
.xsession file launches xpmroot to<br />
set the background image, xmodmap to rebind caps lock to ctrl. It<br />
then launches a status bar program with dzen, before finally<br />
launching xmonad:<br />
<br />
# .xsession<br />
xpmroot ~/.bg/407511721_eb8559457c_o.xpm &amp;<br />
xrdb -merge .Xresources<br />
<br />
xmodmap -e "remove Lock = Caps_Lock"<br />
xmodmap -e "keysym Caps_Lock = Control_L"<br />
xmodmap -e "add Control = Control_L"<br />
<br />
status | dzen2 -ta r -fg '#a8a3f7' \<br />
-bg '#3f3c6d' \<br />
-fn '-*-terminus-medium-r-normal--16-*' \<br />
-e "button1=exec:xterm" &amp; <br />
urxvt &amp;<br />
<br />
$HOME/bin/xmonad<br />
<br />
You may also launch applications from your xmonad.hs, using startupHook, however this runs each time xmonad is restarted with mod-q. Also in > xmonad-0.8 see spawnPid, mkSpawner, spawnOn.<br />
<br />
Use manageHook to arrange your programs on different workspaces by matching various window properties such as className, appName (resource), title, or role.<br />
<br />
===Using floating windows===<br />
Use the regular swap or focus up and down to navigate them, and regular mod-enter to raise a window to the front. For a mod-enter binding, the darcs shiftMaster works better than swapMaster if you use multiple floats over tiled windows. See also this<br />
[[#Force_all_new_windows_down|swapDown manage hook warning]] above. If you use that manageHook on all windows you will create new floats behind existing ones. If you use lots of floats for some reason for better float usability see SimpleFloat layout, FloatKeys, Hooks.Place, and Config.Bluetile in xmonad-contrib.<br />
<br />
===Setting the X cursor===<br />
<br />
By default xmonad doesn't set a particular X cursor, which usually<br />
means the default X cursor will be used by the system. To set your<br />
own custom cursor, use the xsetroot program, as follows, from your<br />
startup file, i.e. .xinitrc, .xsession, display manager startup or<br />
.Desktop files:<br />
<br />
# For example, a nice left-pointing arrow head cursor<br />
<br />
xsetroot -cursor_name left_ptr<br />
<br />
If you have development headers for X11, other cursors can be found in /usr/include/X11/cursorfont.h<br />
<br />
Note that some display managers, such as "slim", don't unset the changes<br />
they make to the cursor when the window manager starts. This can be worked<br />
around by setting the cursor, as above.<br />
<br />
=== Removing the borders around mplayer ===<br />
<br />
You can also use the fullscreen layout, with the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-NoBorders.html NoBorders] smartBorders layout modifier, which automatically takes care of most cases.<br />
<br />
To add 'smartBorders' to the default tiling modes:<br />
<haskell><br />
import XMonad<br />
import XMonad.Layout.NoBorders<br />
<br />
main = xmonad $ <br />
defaultConfig<br />
{ layoutHook = smartBorders $ layoutHook defaultConfig<br />
-- other fields like terminal, modMask, etc.<br />
}<br />
</haskell><br />
<br />
<br />
<br />
You can also remove borders with a key binding using [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-NoBorders.html Actions.NoBorders] extension. There's drawback: you need manually remove border any time you launch mplayer.<br />
<br />
Although this action should be able to be automated, unfortunately you cannot<br />
currently use manageHook for this purpose. That's because borders are drawn<br />
''after'' runManageHook is executed (see Operations.hs for details).<br />
<br />
Alternatively you can manually move the mplayer window 1 pixel to the left and<br />
one pixel up by importing XMonad.Actions.FloatKeys and adding a keybinding<br />
similar to ((modm, xK_b), withFocused (keysMoveWindow (-1,-1)). (I have not<br />
tested yet if this can be used in combination with the manageHook.)<br />
<br />
===I need to find the class title or some other X property of my program===<br />
<br />
If you are using something like XMonad.Actions.WindowGo, or a hook, or some<br />
other feature like that where XMonad needs to know detailed information about a window, you can generally find what you need by splitting your screen between the window and a terminal; in the terminal, run <tt>xprop | grep CLASS</tt> or the like, and then click on the window. xprop will then print out quite a bit of useful information about the window. <br />
* '''resource''' (also known as '''appName''') is the first element in WM_CLASS(STRING)<br />
* '''className''' is the second element in WM_CLASS(STRING)<br />
* '''title''' is WM_NAME(STRING)<br />
<br />
For example, in <code> WM_CLASS(STRING) = "emacs", "Emacs" </code> -- "emacs" is resource (appName), "Emacs" is className.<br />
<br />
(Applications may change the title after window creation, before xprop sees it. If possible, use resource or class in such cases.) stringProperty "WM_WINDOW_ROLE" can also be useful.<br />
<br />
Sample output might look like:<br />
<br />
<pre>_MOTIF_DRAG_RECEIVER_INFO(_MOTIF_DRAG_RECEIVER_INFO) = 0x6c, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0<br />
XdndAware(ATOM) = BITMAP<br />
WM_STATE(WM_STATE):<br />
window state: Normal<br />
icon window: 0x0<br />
WM_HINTS(WM_HINTS):<br />
Client accepts input or input focus: True<br />
Initial state is Normal State.<br />
window id # of group leader: 0xf600001<br />
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 257949716<br />
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL<br />
_NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0xf600013<br />
WM_CLIENT_LEADER(WINDOW): window id # 0xf600001<br />
_NET_WM_PID(CARDINAL) = 476661<br />
WM_LOCALE_NAME(STRING) = "en_US.utf8"<br />
WM_CLIENT_MACHINE(STRING) = "localhost"<br />
WM_NORMAL_HINTS(WM_SIZE_HINTS):<br />
program specified minimum size: 32 by 34<br />
program specified resize increment: 8 by 17<br />
program specified base size: 16 by 0<br />
window gravity: NorthWest<br />
WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST<br />
WM_CLASS(STRING) = "emacs", "Emacs"<br />
WM_ICON_NAME(STRING) = "emacs@craft"<br />
_NET_WM_ICON_NAME(UTF8_STRING) = 0x45, 0x4d, 0x41, 0x43, 0x53<br />
WM_NAME(STRING) = "EMACS"<br />
_NET_WM_NAME(UTF8_STRING) = 0x45, 0x4d, 0x41, 0x43, 0x53<br />
</pre><br />
<br />
Note: the last several lines contain useful information like the CLASS and<br />
hinting information.<br />
<br />
==== What about other properties, such as WM_WINDOW_ROLE? ====<br />
Use <code>stringProperty</code> to extract string information, for<br />
example:<br />
<br />
<pre><br />
stringProperty "WM_WINDOW_ROLE" =? "presentationWidget" --> doFloat<br />
</pre><br />
<br />
For non-string properties, try [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-ManageHelpers.html XMonad.Hooks.ManageHelpers].<br />
<br />
Consult the [http://xmonad.org/xmonad-docs/xmonad/XMonad-ManageHook.html XMonad.ManageHook] documentation for more information.<br />
<br />
==== A handy script to print out window information ====<br />
<br />
This script will print window information (if available) in formats usable within <tt>xmonad.hs</tt>.<br />
<br />
#! /bin/sh<br />
exec xprop -notype \<br />
-f WM_NAME 8s ':\n title =\? $0\n' \<br />
-f WM_CLASS 8s ':\n appName =\? $0\n className =? $1\n' \<br />
-f WM_WINDOW_ROLE 8s ':\n stringProperty "WM_WINDOW_ROLE" =\? $0\n' \<br />
WM_NAME WM_CLASS WM_WINDOW_ROLE \<br />
${1+"$@"}<br />
<br />
It works like <tt>xprop</tt>: by default you click on a window with the crosshairs, or you can specify windows using the <tt>-id</tt> or <tt>-name</tt> options. (The <tt>-root</tt> and <tt>-font</tt> selectors could be used, but are less than useful. Also, <tt>-frame</tt> is unlikely to do anything useful.)<br />
<br />
See [[Xmonad/General_xmonad.hs_config_tips#Matching_specific_windows_by_setting_the_resource_name_or_class|Matching specific windows by setting the resource name or class]] for how you can change what programs use for some of these strings.<br />
<br />
=== What is the xK_ value for this key? ===<br />
Pressing the key of interest while focusing a xev window gives useful information.<br />
To limit xev's output use something like:<br />
<br />
<code>xev | sed -ne '/^KeyPress/,/^$/p'</code><br />
<br />
A complete list can be found at [[Xmonad/Key_codes|XMonad key symbols]].<br />
<br />
=== How can I send a key sequence to a window? ===<br />
<br />
This can be useful when some application uses a hotkey that you<br />
want to use in XMonad, yet be able to send the application window the<br />
hotkey when needed.<br />
<br />
A solution is to use [http://www.semicomplete.com/projects/xdotool/ xdotool], <br />
which can (among other nifty things), send a fake keypress to the<br />
currently focused window. So, for instance, you can use the following<br />
keybinding to send Alt+L to the focused window by pressing Ctrl+Alt+L:<br />
<br />
, ((mod1Mask|controlMask, xK_l), spawn "xdotool key alt+l")<br />
<br />
[http://www.semicomplete.com/projects/xdotool/ xdotool] can also paste<br />
a line of ASCII text into the focused window. For instance, the<br />
following keybinding will insert the email address email@example.org<br />
each time the key Ctrl+Alt+e is pressed:<br />
<br />
, ((mod1Mask|controlMask, xK_e), spawn "xdotool text 'email@example.org'")<br />
<br />
The <code>XMonad.Util.Paste</code> module (currently in the darcs<br />
repository only, will be in 0.9) defines functions to to the same with<br />
pure Haskell code.<br />
<br />
<br />
=== I don't use a statusbar, but I'd like to have layout displayed for some time when it changes ===<br />
<br />
Let's assume you have <hask>import qualified XMonad.StackSet as W</hask> in xmonad.hs.<br />
<br />
Add the following declaration somewhere in the toplevel:<br />
<haskell>curLayout :: X String<br />
curLayout = gets windowset >>= return . description . W.layout . W.workspace . W.current</haskell><br />
<br />
Then add the keybinding:<br />
<haskell><br />
, ((mod1Mask, xK_a ), sendMessage NextLayout >> (curLayout >>= \d->spawn $"xmessage "++d))<br />
</haskell><br />
<br />
You might want to change xmessage to the more friendly program, such as osd_cat, qt-dialog or dzen2.<br />
<br />
Another option is to use<br />
[http://www.xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-ShowWName.html Layout.ShowWName] <br />
which has some user configurable options such as font, color and fade timings.<br />
<br />
More flexible way is to use <code>dynamicLogString</code> from <code>XMonad.Hooks.DynamicLog</code> (was added after 0.6 release), which can also display current workspace, window name, layout, and even arbitrary <hask>[X (Maybe String)]</hask>, and format them nicely, printing them to xmonad's stdout.<br />
<br />
===How can I make xmonad use UTF8?===<br />
<br />
TODO: is this still accurate? Doesn't xmonad-0.8 and greater always use UTF8 with no extra imports or configuration changes?<br />
<br />
Due to extensions like [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html DynamicLog], xmonad is capable of text outputting which is not by default but can be encoded in UTF8. Therefore, if you want to output non-ASCII characters, you can take advantage of the [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/utf8-string System.IO.UTF8] module.<br />
<br />
For example using DynamicLog you can define its output [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-DynamicLog.html#v%3AppOutput ppOutput] like his:<br />
<haskell><br />
import qualified System.IO.UTF8<br />
-- lots of other stuff<br />
ppLog = defaultPP<br />
{ ppOutput = \s -> do<br />
h <- openFile "/home/$USER/.xmonad/xmonad.log" WriteMode<br />
System.IO.UTF8.hPutStrLn h s<br />
hClose h<br />
}<br />
</haskell><br />
<br />
As it may not be ideal to reopen the file before every writing, you can just place the code somewhere else. See ray's config in xmonad's [[Xmonad/Config_archive|config archive]].<br />
<br />
===How do I use compositing with xmonad?===<br />
<br />
Xmonad has the ability to use some compositing features yet still be actually useable ;-). For example, some really nice transparency can be used with a composite aware app like urxvt and xcompmgr. <br />
<br />
First enable compositing in your X server configuration by including the following in your xorg.conf<br />
<br />
<pre><br />
Section "Extensions"<br />
Option "Composite" "enable"<br />
EndSection<br />
</pre><br />
<br />
restart the X server and confirm it's working with xdpyinfo | grep Composite. If it returns Composite, then good...<br />
<br />
Include this in ~/.Xdefaults<br />
<br />
<pre><br />
URxvt.depth: 32<br />
URxvt*background: rgba:0000/0000/0000/cccc<br />
</pre><br />
<br />
this specifies that urxvt uses 32 bit colors and uses a transparent black background. The four c's specify the amount of alpha with ffff being full black and 0000 being fully transparent. You can also use the fading and blurRadius resources to give some nice effects in the transparency. see man urxvt.<br />
<br />
finally you need to fire up xcompgr so that this will all actually work. probably you'll want to include it in your ~/.xinitrc or ~/.xsession file:<br />
<br />
<pre><br />
xcompmgr -c &<br />
</pre><br />
<br />
the -c option provides a soft shadow around your windows. There are many options, see man xcompmgr. <br />
<br />
For an example with screenshots see andrewsw's config in the [[Xmonad/Config_archive|config archive]].<br />
<br />
On newer versions of XMonad, see also '''XMonad.Hooks.FadeInactive''' documentation.<br />
<br />
=== How do I find a function which does ...? ===<br />
<br />
[http://holumbus.fh-wedel.de/hayoo/hayoo.html Hayoo!] API search can be used to find existing functions within XMonad and XMonadContrib which do useful things. For example, the search string<br />
(next AND screen) package:xmonad<br />
will find all existing functions which mention moving to the next Xinerama screen.<br />
<br />
==Troubleshooting==<br />
<br />
===Multi head or xinerama troubles===<br />
====xmonad does not detect my multi-head setup====<br />
<br />
To diagnose the problem, execute the following on the command line:<br />
<br />
ghc -e Graphics.X11.Xinerama.compiledWithXinerama<br />
<br />
If the output is True, skip to the getScreenInfo test below. If the output is False, your Haskell X11 library was not built against Xinerama. This is true of old Debian and Ubuntu packages, and may also occur if you built from source.<br />
<br />
First, be sure that the Xinerama development headers are installed (libxinerama-dev in Debian and Ubuntu).<br />
<br />
Next, check the configure output for the Haskell X11 library for the following lines (If using cabal: cabal install X11 -v --reinstall):<br />
<br />
checking X11/extensions/Xinerama.h usability... yes<br />
checking X11/extensions/Xinerama.h presence... yes<br />
checking for X11/extensions/Xinerama.h... yes<br />
<br />
If any of these lines end in "no", the Xinerama headers are not installed. If the lines end in "yes", execute:<br />
<br />
runghc Setup clean<br />
runghc Setup configure --user --prefix=$HOME<br />
runghc Setup build<br />
runghc Setup install<br />
<br />
In the X11, xmonad and xmonad-contrib source directories. Try the compiledWithXinerama diagnostic again, this time it should return True. As always, execute "xmonad --recompile" when reinstalling any part of xmonad.<br />
<br />
If compiledWithXinerama is True and multi-head still doesn't work, execute "xmonad --recompile" and press mod-q. If the problem persists, execute this command:<br />
<br />
ghc -e "Graphics.X11.openDisplay [] >>= Graphics.X11.Xinerama.getScreenInfo"<br />
<br />
Here is a sample output from a system with two 1280 by 1024 monitors, oriented side by side:<br />
<br />
[Rectangle {rect_x = 0, rect_y = 0, rect_width = 1280, rect_height = 1024}, Rectangle {rect_x = 1280, rect_y = 0, rect_width = 1280, rect_height = 1024}]<br />
<br />
Check to see whether there is a Rectangle corresponding to each of your screens. If there is not, and the compiledWithXinerama diagnostic returns True, there may be a problem with your X server configuration.<br />
<br />
====Missing X11 headers====<br />
<br />
Your build will fail if you've not installed the X11 C library headers<br />
at some point. ./configure for the Haskell X11 library will fail. To<br />
install the X11 C libs:<br />
<br />
* debian<br />
<br />
apt-get install libx11-dev<br />
<br />
====X11 fails to find libX11 or libXinerama====<br />
<br />
Cabal has difficulty locating library directories on some<br />
platforms (such as the Mac or RHEL4). First, locate the<br />
directory that contains libX11.so (libX11.dylib on Mac OS<br />
X). Add the following line to the .cabal file for the<br />
package:<br />
<br />
extra-lib-dirs: /your/path/here/<br />
<br />
For example, on a 64 bit machine you might need to add:<br />
<br />
extra-lib-dirs: /usr/X11R6/lib/lib64<br />
<br />
You can also add the paths to your .buildinfo file, or set the<br />
LD_LIBRARY_PATH environment variable.<br />
<br />
====Something is weird with multi head windows or workspaces (desktops)====<br />
See [[#Multi head and workspaces (desktops)|Configuration: Multi head and workspaces]]<br />
<br />
===X Error of failed request: BadAccess (attempt to access private resource denied)===<br />
This message seen at xmonad's stdout when starting xmonad means that another window manager is already running. If the other WM was started from a DE, you can use [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-Replace.html Util.Replace] to have xmonad ask the other WM to exit before starting up. Note: If exiting your previously running wm would lead to your X session ending, then this method won't work. <br />
<br />
Otherwise refer to the appropriate page for starting xmonad instead of your other WM ([[Xmonad/Using xmonad in Gnome|Gnome]], [[Xmonad/Using xmonad in KDE|KDE]]).<br />
<br />
===mod-q doesn't work===<br />
====Upgraded GHC and now xmonad xmonad-contrib etc are not found====<br />
When you change ghc versions you need to rebuild or reinstall haskell libraries to make sure they are compatible and registered with the new ghc. Often your distro packagers will try to make this as automatic as possible, by making it just happen. Or at least they will make it easier, e.g. gentoo's ghc-updater and haskell-updater. (This isn't just a Haskell/ghc issue; it's true for other languages, too: c.f. python-updater scripts, distro policies regarding gcc and glibc changes.)<br />
<br />
==== Changes to the config file ignored or 'xmonad not found' when starting X ====<br />
<br />
Both ghc and xmonad must be in your display manager init's $PATH when starting X and xmonad for reconfiguration by mod-q. Make sure the environment from which you start xmonad has the appropriate settings.<br />
<br />
When changing the xmonad.hs and restarting with mod-q, xmonad will attempt to exec the xmonad binary. This means it must be in your $PATH environment variable, or the exec will fail silently and the old xmonad instance keeps running.<br />
<br />
With xmonad 0.5 and later, mod-q will also call ghc on your ~/.xmonad/xmonad.hs file, and will continue with defaults if ghc is not found.<br />
<br />
Additionally, if you change and reinstall the haskell-X11 or XMonadContrib library, changes to that package will not be noticed by xmonad's recompilation<br />
checker, so xmonad.hs won't be recompiled. ''(needs confirmation: is this true?)'' To fix this:<br />
<br />
xmonad --recompile<br />
<br />
after reinstalling the contrib library.<br />
<br />
===Tabbed or other decorated layouts not shown===<br />
Both xmobar and xmonad's default <br />
[http://hackage.haskell.org/packages/archive/xmonad-contrib/latest/doc/html/XMonad-Layout-Tabbed.html Theme] <br />
use the <code>-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*</code> font by default. This is<br />
possibly the most commonly installed font in the *nix world, but if it's not installed,<br />
or core fonts aren't working for some reason, you'll have problems. Without the font<br />
you have set in your Theme....<br />
<br />
tabs and other decorated layouts will simply not draw. There should be font related errors<br />
in .xsession-errors or wherever your display manager directs stderr to help confirm that<br />
this is the cause of missing decorations. xmobar will spit out a cryptic error message<br />
and refuse to run.<br />
<br />
Check with xfontsel that you have the fixed 10 font if you want to use the defaults.<br />
For xft, check that your xmonad and xmobar were compiled with xft support. (They are<br />
by default on most distros) Then customize your theme by using something like the<br />
following in your layoutHook<br />
<haskell><br />
myTabbed = tabbed shrinkText defaultTheme {<br />
fontName = "xft:terminus:size=12" -- choose an installed font<br />
-- more theme customizations<br />
}<br />
<br />
main = do<br />
-- skipped<br />
, layoutHook = avoidStruts $ myTabbed ||| layoutHook defaultConfig<br />
} <br />
</haskell> <br />
<br />
===DE panels pagers or EwmhDesktops are broken (just upgraded to >0.8)===<br />
Starting with 0.9, <br />
EwmhDesktops users ''must'' [http://code.haskell.org/XMonadContrib/XMonad/Hooks/EwmhDesktops.hs change configuration] by removing the obsolete ewmhDesktopsLayout from layoutHook, (it no longer exists), and updating to the current ewmh support which still includes a logHook, but in place of the old layout modifier, uses a startupHook and handleEventHook (see ff.).''(No need to change config if using ewmh via Config.Desktop, Config.Gnome, etc. Your config will automatically be updated to use current ewmh support.)<br />
<br />
Users of defaultConfig that explicitly include EwmhDesktops hooks and the ewmhDesktopsLayout modifier should remove them and instead use the new <hask>ewmh</hask> function which adds EWMH support to <hask>defaultConfig</hask> all at once. You should keep avoidStruts and manageDocks if you're using them.<br />
<br />
The 0.9 way to use EwmhDesktops rather than a desktop config is:<br />
<haskell><br />
import XMonad<br />
import XMonad.Hooks.EwmhDesktops<br />
<br />
main = xmonad $ ewmh defaultConfig {<br />
-- normal customizations<br />
}<br />
</haskell><br />
<br />
===defaultGaps doesn't work any more! (just upgraded to >0.7)===<br />
See [[#Make space for a panel dock or tray | Make space for a panel]] section: use XMonad.Hooks.ManageDocks avoidStruts for this instead of Gaps, or import XMonad.Layout.Gaps.<br />
<br />
===Showing fractions of lines in gvim, urxvt,etc.===<br />
<br />
This is due to certain layouts doesn't care about so called size hints<br />
(resize increments) specifically the WM_NORMAL_HINTS(WM_SIZE_HINTS) (use<br />
xprop to see it). This, combined with certain programs, like gvim, which<br />
doesn't check if it gets enough size to render the last line and uses it anyway<br />
render this annoying behaviour. Aside from patching the offending program, you can:<br />
<br />
# Use a layout which uses these size hints like Hinted Grid, or HintedTile<br />
# Use the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-LayoutHints.html layoutHints] modifier on any layout<br />
# Workaround in .vimrc. These lines in your .vimrc lets you change the number of lines with F4/Shift-F4:<br />
<pre><br />
map <F4> :let &lines=&lines-1<CR><br />
map <S-F4> :let &lines=&lines+1<CR><br />
</pre><br />
4. Change the color of default GTK background (white lines), to match gvim background<br />
<pre><br />
style "vimfix" { bg[NORMAL] = "#000000" }<br />
widget "vim-main-window.*GtkForm" style "vimfix"<br />
</pre><br />
===Emacs mini-buffer starts at wrong size===<br />
ontoillogical says: Most people turn off menus and toolbars and adjust fonts in their .emacs. That's what breaks emacs' display in tiling WMs. To get emacs to look correctly, move all of the stuff that affects how emacs draws a frame to .Xdefaults/.Xresources<br />
<br />
For reference here is the relevant section of mine:<br />
<br />
Emacs.font: DejaVu Sans Mono-12<br />
Emacs.fontBackend: xft<br />
Emacs.menuBar: off<br />
Emacs.toolBar: -1<br />
Emacs.verticalScrollBars: off<br />
<br />
If you're having emacs sizing problems setting these in .Xdefaults is still worth a try even if you don't have any custom .emacs settings.<br />
<br />
===Losing text when resizing xterms===<br />
<br />
Being a dynamic tiling window manager, xmonad, like ion or dwm, makes heavy use of resizing. Clients such as xterm, might not take well to resizing and the window might require a refresh (Ctrl-L). To minimize this, several users recommend urxvt (rxvt-unicode), which handles resizing much better.<br />
<br />
=== I just resized my terminal, but the terminal app didn't resize. ===<br />
This is a SIGWINCH bug in the Linux kernel, believe it or not, in the 2.6.26 series. Details here: http://groups.google.com/group/fa.linux.kernel/browse_thread/thread/8044876def45c0b0/4b7f4cd87feafe5e?show_docid=4b7f4cd87feafe5e.<br />
<br />
The simplest solution is to up/downgrade to a kernel version without this bug.<br />
<br />
===XMonad is frozen!===<br />
<br />
==== XMonad stops but the current window still responds to keys ====<br />
<br />
Usually this is because a dynamicLog is writing to a pipe handle that's not being read. For example the xmonad.hs writes to some status bar in the logHook, but the status bar is not installed, not in $PATH, not set up to read its stdin, or just plain not running. Eventually the pipe fills up and blocks and xmonad waits for it to be read before continuing.<br />
<br />
To cat the full pipe and free up xmonad, find xmonad's pid via pgrep or htop, etc. let's say it's 1001, then <code>ls -l /proc/1001/fd/</code> and look for the largest numbered pipe. Let's use 4. Then <code>cat /proc/1001/fd/4</code> to unblock xmonad so you can fix your xmonad.hs and xmobarrc to work correctly. (If catting that pipe doesn't spew out a bunch of stuff and unfreeze things, try the others listed.)<br />
<br />
With the post 0.9 <hask>=<< xmobar</hask> and <hask>statusBar</hask> modifiers it isn't obvious that xmonad is writing to a pipe. If you don't want xmonad info shown in your<br />
status bar, you will probably be better off launching it by other means such as .xinitrc. You can also customize your PP's ppOutput field to use the default <hask>hPutStrLn</hask> to write to stdout, or change it to <hask>\s -> return ()</hask> to do nothing at all.<br />
<br />
<em>With xmobar</em>, if your logHook is writing to its stdin via <hask>ppOutput = hPutStrLn foo</hask>, make sure the .xmobarrc <hask>commands</hask> include a <hask>Run StdinReader</hask> line, and the <hask>template</hask> includes <hask>%StdinReader%</hask>.<br />
<br />
For examples of an .xmobarrc with working StdinReader, see this [https://wiki.archlinux.org/index.php/Xmonad#Using_xmobar_with_xmonad arch linux help page] or [[Xmonad/Config_archive/John_Goerzen%27s_Configuration|John Goerzen's xmonad config tutorial]].<br />
<br />
See also [http://code.google.com/p/xmonad/issues/detail?id=91 this issue] on the xmonad bug tracker.<br />
<br />
==== XMonad stops responding to keys (usually due to unclutter) ====<br />
<br />
The number one cause for this is the 'unclutter' program, which can fool<br />
some clients into thinking they've lost the pointer, when in fact they have<br />
not. See the '-noevents' flag to unclutter.<br />
Or use [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-Warp.html XMonad.Actions.Warp] or [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-UpdatePointer.html XMonad.Actions.UpdatePointer] xmonad-contrib extension instead.<br />
<br />
==== An app seems to have frozen and xmonad stops responding to keys ====<br />
<br />
Often you can get X to behave again by running 'xclock -display :0' on the appropriate display via ssh or from a virtual terminal. If that's not enough kill suspect apps similarly.<br />
<br />
There is also an option in (pre evdev versions of) xorg.conf which enables the key combination '''Ctrl+Alt+Keypad-Divide''' to break active keyboard and mouse grabs. <br />
<br />
This may allow xmonad to continue normally in such cases. To enable this key combination, add the following line to your xorg.conf in the Section ''Server Flags'' then restart X:<br />
<br />
Option "AllowDeactivateGrabs" "on"<br />
<br />
=== Problems with Java applications, Applet java console ===<br />
<br />
The Java gui toolkit has a hardcoded list of so-called "non-reparenting"<br />
window managers. xmonad is not on this list (nor are many of the newer window<br />
managers). Attempts to run Java applications may result in `grey blobs' where<br />
windows should be, as the Java gui code gets confused.<br />
<br />
The following workarounds also fix an issue with Java gui applications where menus are not "selectable". (Clicking on the menu item opens the dropdown list of options but you can't select one, or the menu disappears when you are looking at it.)<br />
<br />
If you are still having focus problems, even after implementing the workarounds, see also<br />
[http://code.google.com/p/xmonad/issues/detail?id=177 issue 177].<br />
<br />
====Preferred Method====<br />
If you are using openjdk6 >= 1.6.1, the cleanest way to work around the hardcoded list is to warn the vm that xmonad is non-reparenting by exporting the appropriate environment variable:<br />
<br />
_JAVA_AWT_WM_NONREPARENTING=1<br />
<br />
Using JDK 7 seems to work well, too, see below.<br />
<br />
====Using SetWMName====<br />
Otherwise, you can lie to Java about what window manager you are using, by having the [http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Hooks-SetWMName.html SetWMName] extension convince Java that xmonad is '''"LG3D"'''. Normally you would use this in<br />
startup hook, like this:<br />
<br />
<haskell><br />
-- etc<br />
import XMonad.Hooks.SetWMName<br />
<br />
main = do<br />
xmonad $ defaultConfig<br />
{ modMask = mod4Mask<br />
, startupHook = setWMName "LG3D"<br />
-- other customizations<br />
}<br />
</haskell><br />
'''However''', modules using Hooks.EwmhDesktops, such as Config.Gnome, Config.Desktops, etc. also set WM Name as part of supporting Extended Window Manager Hints. Combining EWMH support with the "LG3D" workaround takes special attention to modifying the appropriate hook for your xmonad version:<br />
<br />
'''Starting with xmonad-0.9'''. the window manager name is set once in EWMH '''''startupHook''''' after each mod-q, along with other EWMH initialization, but after that can be changed and not overwritten till the next mod-q. See below for example startupHooks combining both startupHooks.<br />
<br />
'''In xmonad versions 0.7 and 0.8''' the EWMH configs setWMName to "xmonad" on each '''''logHook''''' event, so to use "LG3D" instead, it's necessary to either<br />
* patch the XMonad.Hooks.EwmhDesktops source and rebuild xmonad-contrib<br />
OR<br />
* use the version 0.8.* hack shown below to repeatedly setWMName "LG3D" after the ewmh logHook runs.<br />
<br />
==== Using SetWMName with EwmhDesktops ====<br />
<br />
For '''xmonad-0.9 0.9.1 or darcs''':<br />
<br />
Add ewmhDesktopsStartup, (or 'startupHook gnomeConfig', etc.) to '''''startupHook''''' ''before'' setWMName.<br />
<br />
Defining the EWMH hooks yourself:<br />
<haskell><br />
-- etc<br />
import XMonad.Hooks.EwmhDesktops<br />
import XMonad.Hooks.SetWMName<br />
<br />
main = xmonad defaultConfig<br />
{ -- skipped<br />
, startupHook = ewmhDesktopsStartup >> setWMName "LG3D"<br />
}<br />
</haskell><br />
<br />
Using a desktop config as your base:<br />
<haskell><br />
xmonad desktopConfig<br />
{ -- skipped<br />
, startupHook = startupHook desktopConfig >> setWMName "LG3D"<br />
}<br />
</haskell><br />
<br />
If instead you're using the ewmh config modifier to add EWMH support, then define your config at top-level to allow over-riding the startupHook definition with your own version:<br />
<haskell><br />
-- etc<br />
import XMonad.Hooks.EwmhDesktops<br />
import XMonad.Hooks.SetWMName<br />
<br />
-- define an EWMH base config to use later in main<br />
conf = ewmh defaultConfig<br />
{ manageHook = myManageHooks <+> manageDocks <+> manageHook defaultConfig<br />
, layoutHook = avoidStruts $ myLayout ||| layoutHook defaultConfig<br />
, logHook = dynamicLogWithPP xmobarPP<br />
{ ppOutput = hPutStrLn xmproc<br />
, ppLayout = const ""<br />
, ppTitle = xmobarColor "green" "" . shorten 80<br />
}<br />
}<br />
<br />
-- Override the WM Name setting for the "LG3D" workaround<br />
-- but still use the rest of the EWMH base config you just<br />
-- defined, including its startupHook ewmh initialization<br />
<br />
main = do<br />
xmproc <- spawnPipe "xmobar"<br />
xmonad conf<br />
{ startupHook = startupHook conf >> setWMName "LG3D"<br />
}<br />
</haskell><br />
<br />
For '''xmonad-0.8.*''' :<br />
<haskell><br />
-- etc<br />
import XMonad.Hooks.EwmhDesktops<br />
import XMonad.Hooks.ManageDocks<br />
import XMonad.Hooks.SetWMName<br />
<br />
main = do<br />
xmproc <- spawnPipe "xmobar"<br />
xmonad $ defaultConfig<br />
{ manageHook = myManageHooks <+> manageDocks <+> manageHook defaultConfig<br />
, layoutHook = avoidStruts $ ewmhDesktopsLayout $ myLayout ||| layoutHook defaultConfig<br />
-- NOTE: no '$' is used between dynamicLogWithPP and xmobarPP<br />
, logHook = dynamicLogWithPP xmobarPP<br />
{ ppOutput = hPutStrLn xmproc<br />
, ppLayout = const ""<br />
, ppTitle = xmobarColor "green" "" . shorten 80<br />
}<br />
>> ewmhDesktopsLogHook<br />
>> setWMName "LG3D"<br />
<br />
---- or with a desktop config, e.g.<br />
-- , logHook = logHook gnomeConfig >> setWMName "LG3D"<br />
}<br />
</haskell><br />
<br />
With xmonad-0.9 or greater there is no need to spam the X server with setWMName in logHook, see above for how to modify startupHook instead.<br />
<br />
==== Changing AWT Toolkit ====<br />
Another option is to use an AWT toolkit that is more window manager agnostic, (Some report that this causes keyboard to fail in some java applications. It also doesn't seem to work as widely or reliably as setWMName or other preferred methods above.) If you want to try it, set the environment variable:<br />
<br />
AWT_TOOLKIT=MToolkit<br />
<br />
This seems to fix some versions of:<br />
<br />
* MATLAB<br />
* cgoban3<br />
* Netbeans<br />
* processing [http://processing.org]<br />
<br />
Even if you don't use Bash, you can often set environmental variables by putting them in .profile and logging back in:<br />
<br />
export AWT_TOOLKIT=MToolkit<br />
<br />
Using the free blackdown java runtime also seems to work correctly to fix this issue.<br />
<br />
==== Use JDK 7 ====<br />
* Using JDK 7 also seems to work well.<br />
<br />
Anthony Brown writes: <blockquote>I just downloaded and early binary release of JDK 7 and it looks like the new Java version behaves properly ... I tried using some Gui apps that gave me the infamous grey windows with Java6 (or Java5 without setting AWT_TOOLKIT=MToolkit) and so far no problems occured.</blockquote><br />
<br />
Gunnar Ahlberg #xmonad: <blockquote>JDK 7 solved problems remaining even when using setWMName "LG3D" in logHook.</blockquote><br />
<br />
==== Persuade a java application to use a specific java runtime (JRE) ====<br />
<br />
Sometimes it turns out that a program works with a specific JRE version, but not with another. Commercial programs tend to ship with their own JRE, so you may even notice that one program works while another doesn't. (For example, I've had a setup where Maple had problems while Matlab behaved well.) A java symlink in the right place can do wonders here. See [https://bugs.launchpad.net/xorg-server/+bug/185311 this Ubuntu bug report] for a number of examples.<br />
<br />
===XMonad doesn't save my layouts and windows===<br />
<br />
xmonad will remember your workspace layouts during dynamic restart<br />
(mod-q), but not when quitting X altogether. Note that this means <br />
if you add or remove layouts to the config.hs file, the changes won't be<br />
noticed during a hot-restart (the state from the previous session will<br />
be used).<br />
<br />
You can reinitialise the xmonad state dynamically with mod-shift-space.<br />
<br />
===Some keys not working===<br />
If you've an unusual keyboard, X may not know precisely which keys<br />
you've bound xmonad actions to. An example is when you use a<br />
French keyboard layout. You may need to set your own mod key, or use<br />
different key bindings in xmonad.hs. See the xmonad.org docs on configuring and customizing for advice on rebinding keys. Also currently xmonad only handles the first of duplicate key symbols bound, so if you have for example multiple xK_Backspace keys not all will be bound. There are patches available on the xmonad mailing list (or darcswatch) to change this.<br />
<br />
====Media keys====<br />
XMonad.Util.EZConfig additionalKeysP or Graphics.X11.ExtraTypes are the best way to bind the XF86 family of special keys. Note that some special laptop keys are handled by acpi and may show up as button events instead, or even bypass X completely.<br />
<br />
====French keyboard workspace switching====<br />
See XMonad.Config.Azerty for an azertyConfig to use in place of defaultConfig. This will adjust keybindings for the azerty layout, fixing workspaces switching, etc.<br />
<br />
====Numeric keypad keys like xK_KP_2 not working====<br />
Bind to the non-numeric versions of these keys. They work regardless of NumLock status. To avoid conflicts with other apps you probably want to use them with modifiers. Here is an example of using them to navigate workspaces in the usual mod-N mod-shift-N way, but on the key pad:<br />
<br />
<haskell><br />
myWorkspaces = ["1","2","3","4","5","6","7","8","9","0"]<br />
<br />
modm = mod4Mask -- win key for mod<br />
<br />
myKeys = -- use with EZConfig.additionalKeys or edit to match your key binding method<br />
[<br />
-- more custom keybindings<br />
]<br />
++<br />
[((m .|. modm, k), windows $ f i)<br />
| (i, k) <- zip myWorkspaces numPadKeys<br />
, (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]<br />
]<br />
<br />
-- Non-numeric num pad keys, sorted by number <br />
numPadKeys = [ xK_KP_End, xK_KP_Down, xK_KP_Page_Down -- 1, 2, 3<br />
, xK_KP_Left, xK_KP_Begin, xK_KP_Right -- 4, 5, 6<br />
, xK_KP_Home, xK_KP_Up, xK_KP_Page_Up -- 7, 8, 9<br />
, xK_KP_Insert] -- 0 <br />
</haskell><br />
<br />
====Keybindings dont work with rdesktop====<br />
Try running with the "-K" (keep window manager key bindings) switch. For example, <code>rdesktop -K -f 666.666.666.666</code> then press Ctrl-Alt-Enter, or simply <code>rdesktop -K 666.666.666.666</code><br />
<br />
===Copy and Paste on the Mac===<br />
<br />
When using X11 for Mac OS X, and you switch from the quartz WM to<br />
xmonad, you can lose copy/paste functionality between X windows and<br />
normal Mac apps. To fix this, and restore copy and paste, add<br />
<br />
quartz-wm --only-proxy &<br />
<br />
in your .xinitrc above the line that runs xmonad. It will capture and<br />
syncronize copy/paste events in both environments. More specifically,<br />
it mirrors OS X copy actions into both PRIMARY and CLIPBOARD, but only<br />
CLIPBOARD into OS X paste.<br />
<br />
===OpenOffice looks bad===<br />
<br />
OpenOffice won't use (strangely) the GTK look, unless the following<br />
environment variable is set:<br />
<br />
OOO_FORCE_DESKTOP=gnome<br />
<br />
Use this if you don't like the default look of OpenOffice in xmonad.<br />
<br />
=== Help! xmonad just segfaulted ===<br />
<br />
Due to this bug in GHC's recompilation checker,<br />
<br />
http://hackage.haskell.org/trac/ghc/ticket/1372<br />
<br />
if you updated a previously built xmonad, or XMonadContrib, when a<br />
dependent library has changed in the meantime, GHC will happily go ahead<br />
and link your libraries together, into a broken binary. This will at<br />
best produce a linker error, and at worst, a version of xmonad that will<br />
segfault. <br />
<br />
The rule is: when rebuilding, for example, XMonadContrib, always clean<br />
first if any library it depends on has changed.<br />
<br />
runhaskell Setup.lhs clean<br />
<br />
You may also want to make sure your config gets rebuilt:<br />
<br />
xmonad --recompile<br />
<br />
Another possibility is your xmonad was compiled against a very old<br />
version of the haskell-x11 library. Use haskell-X11-1.4.2 or newer.<br />
This version incorporates a couple of WM_HINTS related segfault bug<br />
fixes.<br />
<br />
=== Cabal: Executable stanza starting with field 'flag small_base description' ===<br />
<br />
When using ghc 6.6, or old versions of Cabal, you may get errors when configuring:<br />
<br />
*** Exception: getSection got a line without a '{'. Consider this a bug.<br />
<br />
These are all symptoms of trying to compile xmonad with an old version<br />
of cabal.<br />
<br />
The darcs version after xmonad 0.4 switched to requiring Cabal 1.2 to<br />
build xmonad. You '''must''' have Cabal 1.2 or newer to build xmonad<br />
older than 0.4. It will work fine with ghc 6.6.1, and you do not need to<br />
updated ghc. This will also not break older packages. Get cabal from Hackage:<br />
<br />
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Cabal<br />
<br />
Build and install as usual, then rebuild xmonad.<br />
<br />
To build Cabal with ghc 6.6.1 you will also need the filepath library,<br />
which is also (of course) available from hackage:<br />
<br />
http://hackage.haskell.org/cgi-bin/hackage-scripts/package/filepath<br />
<br />
=== A manage hook is having no effect ===<br />
<br />
If a manage hook that checks an attribute of a window(e.g. resource =? "foo"<br />
--> bar) doesn't work even though the property is the same as reported by<br />
xprop, it can be caused by a program setting the corresponding property after<br />
the window has been created. To debug whether or not the term on the right<br />
hand side is at fault, it is useful to log which resource (or other property)<br />
xmonad sees:<br />
<br />
<haskell><br />
(resource >>= io . appendFile "/home/<youruser>/xmonad_debug" >> idHook)<br />
</haskell><br />
<br />
If opening the desired window causes xmonad to produce a log entry with the<br />
resource you were interested in, it means that the term on the right-hand side<br />
of --> is not working.<br />
<br />
[[Category:XMonad]]</div>Enoksrdhttps://wiki.haskell.org/index.php?title=GHCi_in_colour&diff=36780GHCi in colour2010-09-16T01:53:42Z<p>Enoksrd: added link to blog post with another approach</p>
<hr />
<div>This page documents efforts to colourise GHCi output.<br />
<br />
== Example ==<br />
<br />
[[Image:Colour-ghci.png]]<br />
<br />
Or a type error:<br />
<br />
[[Image:Coloured-error.png]]<br />
<br />
Output like this would be the result of running, for example:<br />
<br />
ghci --colour<br />
<br />
and would appear in the console/xterm as ansi terminal coloured output.<br />
<br />
== Implementation ==<br />
<br />
=== Using sed and ghci.conf ===<br />
<br />
You can use sed to color the non-prompt output, and color the prompt with ghci.conf. This works better than piping into HsColour for me. See [http://martijn.van.steenbergen.nl/journal/2010/02/27/colors-in-ghci/ this] blog post for details.<br />
<br />
=== Using HsColour ===<br />
<br />
An existing tool, [http://www.cs.york.ac.uk/fp/darcs/hscolour/ HsColour], <br />
could be modified to operate interactively. In fact, HsColour is already interactive, and<br />
with a small patch added on 2006-12-14 to control ouput buffering better, this works<br />
relatively nicely:<br />
<br />
ghci 2>&1 | HsColour -tty<br />
<br />
[[Image:Tty.png|frame|HsColour in action]]<br />
<br />
There are small delays however, when lexing certain tokens, and the<br />
interaction with readline isn't ideal.<br />
<br />
=== GuiHaskell ===<br />
<br />
Neil Mitchell has a prototype [http://www-users.cs.york.ac.uk/~ndm/projects/guihaskell.php gui haskell] wrapper, based on gtk. Does this contain a reasonable ghci wrapper we could steal?<br />
<br />
<br />
If you have an idea of how to do this nicely, add your proposal here.<br />
<br />
[[Category:Tools]]</div>Enoksrd