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


72

我想要一个TemplateHaskell函数variablesInScope :: Q [Name],该函数返回Name范围中所有变量的列表。TemplateHaskell显然具有可用的信息,以实现诸如reify :: Name -> Q Info和的功能lookupValueName :: String -> Q (Maybe Name)

我想要的功能是否存在于某个地方而我只是忽略了它?还是可以通过某种方式轻松构建?


2
我相当确定您不能仅使用TH来做到这一点,但是您可以将haskell-src-metaHaskell模块解析为TH AST。
user2407038

1
是否需要使用Qmonad的IO功能来加载模块,然后将其发送给haskell-src-meta?ike。同样,这也不能消除在接头所在的特定范围内使用哪个名称的歧义。
Mike Izbicki 2014年

1
是的,您需要使用IO来实际读取文件。我不确定我是否理解您的第二句话-如果您要获得所有名字,为什么还要消除歧义?您可以为功能请求打开票证,我怀疑为TH提供支持的基础机制无论如何都可以使用所有范围内的名称。
user2407038 2014年

1
我创建了tickect(#9699)。第二点我的意思是,一个函数可能会声明一个名为的变量print,然后printfromSystem.IO不再在范围内。因此,结果variablesInScope取决于在代码中发生拼接的位置非常复杂。
Mike Izbicki 2014年

Answers:


2

不幸的是,您不能TH独自做到这一点。尝试将haskell-src-metaHaskell模块解析为TH AST

但是,将需要Qmonad的IO功能来加载模块。

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

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

(2)添加thisModule :: Q Module产生当前的Module。

(3)添加topLevelNames :: Q [Name]生成绑定在当前模块中的可视化顶级名称列表(已导出和未导出)。

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

(5)添加parentNames :: Q [Name](还需要一个更好的名称),生成一个与当前剪接上下文直接相关的名称列表(如果有)。例如,foo,bar :: $(typeSplice)将看到[foo,bar],foo = $(exprSplice)将看到[foo],而$(topLevelDecSplice)将看到[]。

(6)可选的Add isTopLevel :: Name-> Q Bool来检测名称是否绑定在(当前模块的)顶层。可以通过搜索topLevelNames来完成类似的操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.