[Haskell-cafe] some questions about Template Haskell

oleg at okmij.org oleg at okmij.org
Sun Jun 30 10:33:13 CEST 2013

TP wrote:
> pr :: Name -> ExpQ
> pr n = [| putStrLn $ (nameBase n) ++ " = " ++ show $(varE n) |]

The example is indeed problematic. Let's consider a simpler one:

> foo :: Int -> ExpQ
> foo n = [|n + 1|]

The function f, when applied to an Int (some bit pattern in a machine
register), produces _code_. It helps to think of the code 
as a text string with the
source code. That text string cannot include the binary value that is
n. That binary value has to be converted to the numeric text string, and
inserted in the code. That conversion is called `lifting' (or
quoting). The function foo is accepted because Int is a liftable type,
the instance of Lift. And Name isn't. 

BTW, the value from the heap of the running program inserted into the
generated code is called `cross-stage persistent'. The constraint Lift
is implicitly generated by TH when it comes across a cross-stage
persistent identifier.  You can read more about it at

Incidentally, MetaOCaml would've accepted your example, for now. There
are good reasons to make the behavior match that of Haskell.

More information about the Haskell-Cafe mailing list