我想要一个TemplateHaskell函数variablesInScope :: Q [Name]
,该函数返回Name
范围中所有变量的列表。TemplateHaskell显然具有可用的信息,以实现诸如reify :: Name -> Q Info
和的功能lookupValueName :: String -> Q (Maybe Name)
。
我想要的功能是否存在于某个地方而我只是忽略了它?还是可以通过某种方式轻松构建?
我想要一个TemplateHaskell函数variablesInScope :: Q [Name]
,该函数返回Name
范围中所有变量的列表。TemplateHaskell显然具有可用的信息,以实现诸如reify :: Name -> Q Info
和的功能lookupValueName :: String -> Q (Maybe Name)
。
我想要的功能是否存在于某个地方而我只是忽略了它?还是可以通过某种方式轻松构建?
Q
monad的IO功能来加载模块,然后将其发送给haskell-src-meta
?ike。同样,这也不能消除在接头所在的特定范围内使用哪个名称的歧义。
print
,然后print
fromSystem.IO
不再在范围内。因此,结果variablesInScope
取决于在代码中发生拼接的位置非常复杂。
Answers:
不幸的是,您不能TH
独自做到这一点。尝试将haskell-src-meta
Haskell模块解析为TH AST
。
但是,将需要Q
monad的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来完成类似的操作。
haskell-src-meta
Haskell模块解析为TH AST。