[Haskell-cafe] some questions about Template Haskell
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.
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
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" |] )
> $( lift "u" )
But if I replace a working version:
pr n = [| putStrLn ( $(lift( nameBase n ++ " = " )) ++ show $(varE n) ) |]
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.
More information about the Haskell-Cafe