[Haskell-cafe] some questions about Template Haskell

TP paratribulations at free.fr
Mon Jul 1 00:01:19 CEST 2013


oleg at okmij.org 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.

Thanks Oleg,
Probably the following question will be stupid, but I ask it anyway: in my 
initial example, (nameBase n) returns a String, so we are not in the case 
where it is not "liftable"? In fact I am not sure to have understood your 
answer.

Now, I have found another behavior difficult to understand for me:

> runQ $ lift "u"
ListE [LitE (CharL 'u')
> runQ $ [| "u" |]
LitE (StringL "u")

So we have similar behaviors for lift and [||]. We can check it in a splice:

> $( [| "u" |] )
"u"
> $( lift "u" )
"u"

But if I replace a working version:

pr n = [| putStrLn ( $(lift( nameBase n ++ " = " )) ++ show $(varE n) ) |]

by

pr n = [| putStrLn ( $([| (nameBase n) ++ " = " |]) ++ show $(varE n) ) |]

I again get the error 

"""
No instance for (Lift Name) arising from a use of `n'
Possible fix: add an instance declaration for (Lift Name)
In the first argument of `nameBase', namely `n'
"""

It is not easy to surmise the reason for this error.

TP




More information about the Haskell-Cafe mailing list