使用 TemplateHaskell 列出命名空间中的所有名称

我想要一个 TemplateHaskell 函数 variablesInScope :: Q [Name],它返回范围内所有变量的 Name列表。TemplateHaskell 显然有这些信息可用于实现诸如 reify :: Name -> Q InfolookupValueName :: String -> Q (Maybe Name)之类的函数。

我想要的函数是否存在于某个地方,而我只是忽略了它? 或者它是否可以以某种方式轻松构建?

1062 次浏览

遗憾的是,仅使用 TH无法做到这一点。

但是,它需要 Q单子的 IO 特性来加载模块。

请参考 https://ghc.haskell.org/trac/ghc/ticket/9699#ticket查看当前的粗略规格

(1)将 ModuleInfo (从 reifyModule 获取)扩展到 ModuleInfo [ Module ][ Name ] ,其中[ Module ]仍然是导入列表,[ Name ]包含模块导出的名称列表。

(2)添加 this 模块: : Q 模块生成当前模块。

(3)添加 topLevelNames: : Q [ Name ]生成当前模块中绑定的顶级名称(包括导出的和未导出的)的列表,这些名称可以被具体化。

(4)添加 nestedNames: : Q [ Name ](需要更好的名称) ,生成一个非顶级(嵌套)名称的列表,以便在这个上下文中具体化。

(5)添加 ParentNames: : Q [ Name ](也需要一个更好的名称)生成与当前拼接上下文直接关联的名称列表(如果可用的话)。例如,foo,bar: : $(typeSplice)将看到[ foo,bar ] ,foo = $(expSplice)将看到[ foo ] ,而 $(topLevelDecSplice)将看到[]。

(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.