
oleg@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