Template Haskell: Calling `reify` on a Function Name

Hi all. I’m trying to make a custom Template Haskell deriver based on both a type and a function definition. I’d like to write something like:

deriveMyClass ''MyType 'myDef

and then have deriveMyClass call reify on both MyType to get type information and myDef to get information about that particular function definition.

My understanding is that reify currently doesn’t provide function definitions because of lack of interest (not because of some fundamental limitation). Is that true? How hard would it be to add that? I’m fine if this only works for locally defined functions.

Thanks!

1 Like

If you’re fine with locally defined functions, you could do like singletons, taking the function declaration as an argument, then the deriving function could splice the declaration together with the stuff derived from it:

deriveMyClass ''MyType [d| myDef = foo |]

There’s also the option of using IO in TH to grab definitions right from the source.

Both of these make sense, but neither is particularly satisfying. The first requires a user to rewrite their code (awkwardly sticking a potentially large definition into a macro) and the second seems like it could be fragile and hard to give good error messages for. I’ll stick with the definition in the macro for now, but it’d be great if that wasn’t necessary in the future.

1 Like

Here is the link to the issue in case anyone is interested: #14474: reify RHS of "value" variable · Issues · Glasgow Haskell Compiler / GHC · GitLab

The main blockers are that:

  • the compiler doesn’t always know definitions of variables. Interface Files with Core Definitions - Well-Typed: The Haskell Consultants takes us a long way towards making this available
  • even if we do know the definition, it’s likely to just be Core (ie, the compiler’s internal reprsentation) rather than surface syntax or TH ASTs. We’d have to convert that into TH ASTs, which is doable but a bit tedious. Alternatively (and my preferred fix) is that we should just directly give users Core or a Core-like AST. That’s a lot truer to what the compiler knows and it’s a lot less likely to break

I see. I guess my intuition is that within the same file there should be enough information to provide the TH AST, but I also don’t know any of the real compiler internals here so I believe you if you say it’s too hard. I think in this case a Core AST wouldn’t be as useful — the compilation process might throw away information that I needed from the original AST — so maybe I’m better off using one of @Lysxia’s suggestions either way.

Perhaps you could make your deriver a source plugin?

https://downloads.haskell.org/ghc/latest/docs/users_guide/extending_ghc.html#source-plugins