3

An example is worth a thousand words. Here is a pretty simple quasi quoter I just made up.

import Language.Haskell.TH.Quote
import Language.Haskell.TH.Syntax

quoter :: QuasiQuoter
quoter = QuasiQuoter { quotePat = parse }
  where
    parse :: String -> Q Pat
    parse ('$':x) = pure (VarP (mkName x))
    parse "_" = pure WildP
    parse _ = fail "Invalid pattern"

Then, using it in GHCi

ghci> :set -XQuasiQuotes
ghci> [quoter|_|] = 2
ghci> [quoter|$x|] = 2
ghci> x
error: Variable not in scope: x

I would have liked 2 to be bound to x. So: is there any way to introduce variable patterns in custom quasi-quotes that we can use again? Note that my actual use case is a fair bit more involved than the above - parse actual does some substantial work.

EDIT

The following works:

 ghci> inc [quoter|$x|] = x + 1
 ghci> inc 2
 3

and the following doesn't

 ghci> let [quoter|$x|] = 1 in x
 error: Variable not in scope: x

so is this a bug in GHCi?

Alec
  • 31,829
  • 7
  • 67
  • 114
  • Cannot reproduce the behaviour in GHC 7.10.3. – Zeta Mar 23 '17 at 06:20
  • @Zeta Cool. I'll try it out on 7.10.3 just to double check, then I'll file a bug. I'll post back here once that's done. – Alec Mar 23 '17 at 06:25
  • [Filed as a bug](https://ghc.haskell.org/trac/ghc/ticket/13473#ticket). Note I'm not convinced this is even really a bug.... – Alec Mar 23 '17 at 19:24
  • You can also reproduce the behaviour with `let $(varP . mkName "x") = 1 in x`. And `-ddump-splices` says that the name gets expanded to `x`. So the behaviour affects TH as whole, not only QQ. – Zeta Mar 23 '17 at 22:28

1 Answers1

0

This is now fixed in GHC 8.2 (see this commit).

Alec
  • 31,829
  • 7
  • 67
  • 114