[Haskell-cafe] Scoping in template haskell
ryani.spam at gmail.com
Wed Mar 19 13:46:54 EDT 2008
First off, the first code isn't doing exactly what you think; gen1 3,
for example, generates the parse tree:
"<<" ++ show 3 ++ ">>"
You can improve this in the following way:
gen1 i = let x = "<<" ++ show i ++ ">>" in [| x |]
which generates (for gen1 3, again)
['<', '<', '3', '>', '>']
Alternatively, you can generate the expression directly:
gen1 i = LitE $ StringE $ "<<" ++ show i ++ ">>"
which gives you exactly the parse tree
Now, the compiler will definitely treat the last two the same, but I'm
not sure it will constant-fold "show 3" into "3" in your case.
The "runQ" trick is really useful; in ghci; just use runQ with the
code that you want to generate:
> :set -fth
> :m +Language.Haskell.TH
> runQ [| "<<42>><<66>>" |]
LitE (StringL "<<42>><<66>>")
You then just need to figure out how to make that object from the
inputs you have.
Also, here's something simple to try:
appendStrQ :: [ExpQ] -> ExpQ
appendStrQ = foldr (\x rest -> [| $(x) ++ $(rest) |]) [| "" |]
gen2 = appendStrQ . map gen1
On Wed, Mar 19, 2008 at 5:17 AM, Lars Oppermann <loppermann at acm.org> wrote:
> Hi all,
> I am trying to get familiar with template haskell and I'm wondering
> whether the following is possible and if so, how it would be done
> I have two templates, and I'd like to use one from the other. For
> instance the first one might be
> gen1 :: Int -> ExpQ
> gen1 i = [| "<<" ++ (show i) ++ ">>" |]
> Thus, I gould do
> > $(gen1 42)
> and I'd get "<<42>>"
> now I'd like to use gen2 in another generated expression so that I could so
> > $(gen2 [42, 66])
> and get "<<42>><<66>>"
> My naive intention was to write
> gen2 :: [Int] -> ExpQ
> gen2 is = [| map (\x -> $(gen1 x)) is |]
> which gives me "Stage error: `x' is bound at stage 2 but used at stage 1
> So I guess my actual question would be: how do I pass a variable bound
> outside a quotation into another splice used in that quotation?
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
More information about the Haskell-Cafe