Using TemplateHaskell to list all names in a namespace
HaskellTemplate HaskellHaskell Problem Overview
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?
Haskell Solutions
Solution 1 - Haskell
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.