
John Lato wrote:
The problem isn't the output of nameBase, it's the input parameter 'n'. In your example, you've created a function that takes input (a Name) and generates code based upon that input. In order to lift a value (n) from an ordinary context into a quote, it needs a Lift instance.
:i lift class Lift t where
Thanks John. Ok I can understand that a Lift instance is needed, but to use the lift function below, we also need a Lift instance for the return of (nameBase n), because lift is a function that operates on instances of the Lift typeclass: lift :: t -> Q Exp And it is indeed the case:
:i Lift [...] instance Lift a => Lift [a] instance Lift Char
And as I have shown on a small example, lift and [||] return about the same result:
runQ $ lift "u" ListE [LitE (CharL 'u') runQ $ [| "u" |] LitE (StringL "u")
So what is the difference between lift and [||]? Although I feel stupid, I cannot lie and claim I have understood.
Perhaps it helps if you think about what a quote does: it allows you to write essentially a string of Haskell code that is converted into an AST. For this to work, the quote parser needs to know how to generate the AST for an identifier. Like much of Haskell, it's type-driven. For identifiers in scope from imports, TH simply generates a variable with the correct name. But for data, the parser needs a way to generate an AST representation, which is what Lift is for.
Ok, I think I understand that (we need some method to transform a value at data level in a token of an AST), but it seems to me it does not answer my question above. But I am probably wrong. Thanks TP