4

Can I always expect the single single-quote syntax to desugar to the NameG constructor? e.g. does

'x

always desugar to

(Name (OccName "x") (NameG VarName (PkgName "some-package") (ModName "SomeModule")))

This information must always be there, after name resolution, which is the stage Template Haskell runs after, right? And I haven't been able to quote local names, though I'm only interested in quoting top-level names.

Context: I want to write a function that returns the uniquely-qualified identifier. It's a partial function because I can't constrain the input, as Template Haskell doesn't have any GADTs or anything, while I don't want to wrap the output in uncertainty. And I don't want to use a quasi-quoter or splice, if ' will do. I want to prove that this partial function is safe at runtime when used as above, quoting top-level names in the same module, given:

name (Name occ (NameG _ pkg mod)) = Unique occ pkg mod

I want to have a function like:

(<=>) :: Name -> a -> Named a

given:

data Named a = Named a Unique

to annotate variable bindings:

x = 'x
 <=> ...

without the user needing to use the heavy splice syntax $(name ...), and invoke splicing at compile time:

x = $(name 'x)
 <=> ...

The user will be writing a lot of these, for configuration.

https://downloads.haskell.org/~ghc/7.8.3/docs/html/users_guide/template-haskell.html and https://hackage.haskell.org/package/template-haskell-2.8.0.0/docs/src/Language-Haskell-TH-Syntax.html#Name didn't say.

(p.s. I'd also like to know if the double single-quote syntax (e.g. ''T) had the analogous guarantee, though I'd expect them to be the same).

sam boosalis
  • 1,997
  • 4
  • 20
  • 32
  • 1
    `let x = () in $(stringE $ Data.Generics.gshow 'x)` evaluates to `"(Name (OccName \"x\") (NameL (1627422417)))"` – aavogt Jan 13 '15 at 01:44

1 Answers1

1

Since ' quoted names are known at compile time, why don't you change name to be in the Q monad:

name :: Name -> ExpQ
name (Name occ (NameG _ pkg mod)) = [| Unique occ pkg mod |]
name n = fail $ "invalid name: "++ gshow n

Then you use $(name 'show) :: Unique instead of name 'show :: Unique. If you get an invalid Name (say somebody uses mkName), that failure will show up at compile time.

aavogt
  • 1,308
  • 6
  • 14