Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using TemplateHaskell to list all names in a namespace

I want a TemplateHaskell function variablesInScope :: Q [Name] that returns a list of the Name's of all the variables in scope. TemplateHaskell obviously has this information available in order to implement functions like reify :: Name -> Q Info and lookupValueName :: String -> Q (Maybe Name).

Does the function I want exist somewhere and I just overlooked it? Or can it be easily built somehow?

like image 403
Mike Izbicki Avatar asked Oct 16 '14 00:10

Mike Izbicki


1 Answers

Unfortunately, you cannot do this with TH alone. Try the haskell-src-meta to parse the Haskell module as a TH AST.

It will require the IO features of the Q monad to load the module though.

Please reference https://ghc.haskell.org/trac/ghc/ticket/9699#ticket to see the current rough spec

(1) Extend ​ModuleInfo (obtained from ​reifyModule) to ModuleInfo [Module] [Name], where [Module] is still the import list and [Name] contains the module's list of exported names.

(2) Add thisModule :: Q Module producing the current ​Module.

(3) Add topLevelNames :: Q [Name] producing a list of top-level names (both exported and non-exported) bound in the current module that would be visible to reify.

(4) Add nestedNames :: Q [Name] (in need of a better name) producing a list of the non-top-level (nested) names visible to reify in this context.

(5) Add parentNames :: Q [Name] (also in need of a better name) producing a list of the names immediately associated with the current splicing context, if available. For example, foo, bar :: $(typeSplice) would see [foo, bar], foo = $(exprSplice) would see [foo], and $(topLevelDecSplice) would see [].

(6) Optional Add isTopLevel :: Name -> Q Bool to detect whether a name is bound at the top level (of the current module?). Something like this could alternately be accomplished by searching through topLevelNames.

like image 179
Kirk Strobeck Avatar answered Oct 10 '22 10:10

Kirk Strobeck