# First stab at Template Haskell

Template Haskell is a nice extension to Haskell (but only available in GHC as for now). It is reminiscent of the macro mechanism as found in Scheme or Lisp. While in Lisp the concrete syntax and the representation of the code, i.e. the abstract syntax tree, have no difference, the abstract syntax tree for TH is represented with normal Haskell data types.

The documentation of the package is quite terse but `ghci`

is a nice tool to get started. Start `ghci`

with TH enabled, and load the AST data types :

```
> ghci -XTemplateHaskell
ghci> :m + Language.Haskell.TH
```

To see what is the data structure needed by TH to generate the code `\x -> 1`

, we can run

```
ghci> runQ [| \x -> 1 |]
LamE [VarP x_0] (LitE (IntegerL 1))
```

The `[| |]`

are called Oxford brackets and make it easy to get the AST of some Haskell code (E stands for expression and P for pattern).

We can see a function is a `LamE`

object with some patterns (here, just one variable) and a representation of an expression, the result of the function (here, the literal `1`

).

```
ghci> :t it
it :: Exp
```

(`it`

is a special variable in `ghci`

that allows us to reference the last computed value.) So we have an `Exp`

, representing the Haskell code `\x -> 1`

.

So how can we generate back the code from the `Exp`

? The answer lies in another special syntax, `$(...)`

. The `...`

has to be of type `ExpQ`

, an alias for the type `Q Exp`

. `Q`

is the quotation monad which makes possible, in particular, to draw unique identifiers (that's why there is a `0`

appended to the initial name `x`

, in `VarP x_0`

above) and we can extract the resulting `Exp`

by using `runQ`

.

```
ghci> $(return it)
<interactive>:1:0:
No instance for (Show (t1 -> t))
arising from a use of `print' at <interactive>:1:0-11
Possible fix: add an instance declaration for (Show (t1 -> t))
In a stmt of a 'do' expression: print it
```

The error message we get from `ghci`

is precisely the same we would get if we'd typed directly

`ghci> \x -> 1`

With something that can be actually printed :

```
ghci> runQ [| 1 + 2 |]
InfixE (Just (LitE (IntegerL 1))) (VarE GHC.Num.+) (Just (LitE (IntegerL 2)))
ghci> $(return it)
3
```

Note the possibility to splice (i.e. use `$(...)`

) inside a quotation :

```
ghci> runQ [| 1 + $([| 2 |]) |]
InfixE (Just (LitE (IntegerL 1))) (VarE GHC.Num.+) (Just (LitE (IntegerL 2)))
```

One more thing : the quotation we used was to create expressions and has type `Q Exp`

but there are also quotations for type signatures and declarations, which have respectively the type `Q Typ`

and `Q [Dec]`

.

```
ghci> runQ [t| IO Int |]
AppT (ConT GHC.IOBase.IO) (ConT GHC.Types.Int)
ghci> runQ [d| f a = 1 |]
[FunD f [Clause [VarP a_4] (NormalB (LitE (IntegerL 1))) []]]
```

Now, if you need to generate some Haskell code, you can write, in Haskell, a function which produces a TH AST and then splice it. Beware that you can't write a splice involving a function defined in the same file; you have to import that function to use it. If it happens, you'll simply get a 'stage restriction' error. Have fun with Haskell-generating Haskell.