6

I'm writing a template haskell splice, and am struggling to generate the right kind of Names. If I want to generate a known name (say, a function f), I can use 'f. This requires f to be in scope where I'm defining the splice, not where it's used, which is exactly what I want.

Now I want the same thing, but for a dynamic name. For example, say my splice takes an n :: Int as an argument. I want to generate "f" ++ show n as a Name, looked up at the splice definition site, not the use site.

I've tried a couple of options: mkName and lookupValueName both require the name to be in scope at the use site. The single quote syntax needs a literal name, not a dynamic one.

Finally I started experimenting with mkNameG. Since the functions come from the same package as I'm using them in, I started with the package name, but that gave errors Can't find interface-file declaration for variable the-package-name:Some.Module.f0. After some source reading I found places where the package name "main" was used. That seems to work in GHCi, but when compiling I still get the same error.

Is there any way to do this? I could enumerate all the options of course, but I'd like to avoid that, since the whole point of this exercise is to make the code more dynamic.

Erik Hesselink
  • 2,420
  • 21
  • 25

1 Answers1

1

I imagine you can do this by extracting the package name from a particular Name 'f0, then passing it to mkNameG_v. This might not be a good idea for two reasons:

  • Writing 'f checks that the identifier f really is in scope, whereas you can pass anything to mkNameG and not get an error until you try to use the Name in some way. You'll have to ensure in some other way that you only build Names for identifiers that actually exist, or recover from the error when you use the Name (unless you just want to let GHC fail with the error you saw).

  • Writing 'f also counts as a use of f. Unused unexported definitions are simply discarded, so you will not be able to refer to them with mkNameG. You will have to find some other way to ensure that your "f" ++ show n identifiers are used.

Reid Barton
  • 14,951
  • 3
  • 39
  • 49
  • Thanks, that works great! The two problems you mention might not actually be problematic in my case, since: 1) The identifiers are generated by TH as well, from the same inputs, and 2) The definitions are exported. Thinking about 1 some more, it occurs to me that I might merge the two pieces of TH and get rid of the problem altogether though... – Erik Hesselink May 19 '16 at 17:54