[Haskell-cafe] Scoping in template haskell

Ryan Ingram 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
  "<<3>>".

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

  -- ryan

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
>  properly...
>
>   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?
>
>  Bests,
>  Lars
>  _______________________________________________
>  Haskell-Cafe mailing list
>  Haskell-Cafe at haskell.org
>  http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list