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

使用TemplateHaskell列出命名空间中的所有名称,haskell,template-haskell,Haskell,Template Haskell,我需要一个TemplateHaskell函数VariablesScope::Q[Name],它返回作用域中所有变量的名称的列表。TemplateHaskell显然可以使用这些信息来实现像reify::Name->Q Info和lookupValueName::String->Q(可能是Name)这样的函数 我想要的功能是否存在于某个地方,而我只是忽略了它?或者它可以以某种方式轻松构建吗?不幸的是,您无法单独使用TH来实现这一点。尝试使用haskell src meta将haskell模块解析为T

我需要一个TemplateHaskell函数
VariablesScope::Q[Name]
,它返回作用域中所有变量的
名称的列表。TemplateHaskell显然可以使用这些信息来实现像
reify::Name->Q Info
lookupValueName::String->Q(可能是Name)
这样的函数


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

不幸的是,您无法单独使用
TH
来实现这一点。尝试使用
haskell src meta
将haskell模块解析为
TH AST

它需要
Q
monad的IO功能来加载模块

请参考以查看当前的粗略规格

(1) 延伸​ModuleInfo(从​reifyModule)到ModuleInfo[Module][Name],其中[Module]仍然是导入列表,[Name]包含模块的导出名称列表

(2) 添加thisModule::Q模块,生成当前​模块

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

(4) addnestednames::Q[Name](需要更好的名称)生成在此上下文中可具体化的非顶级(嵌套)名称列表

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

(6) 可选的Add-isTopLevel::Name->Q Bool,用于检测名称是否绑定在(当前模块的)顶层。类似的事情也可以通过搜索顶级名称来实现


我很确定你不能只用TH来完成这项工作,但是你可以使用
haskell src meta
将haskell模块解析为TH AST。这是否需要使用
Q
monad的IO功能来加载模块,然后将其发送到
haskell src meta
?哎呀。此外,这无法消除在拼接所在的特定范围内使用哪个名称的歧义。是的,您需要使用IO来实际读取文件。我不确定我是否理解你的第二句话——如果你得到了所有的名字,为什么你需要消除歧义?你可以为一个功能请求打开一个票证,我怀疑驱动TH的底层机制无论如何都有所有作用域内的名称可用。第二点的意思是,函数可能声明一个名为
print
的变量,然后
System.IO
中的
print
将不再在范围内。因此,
variablesInScope
的结果与拼接发生在代码中的位置有着相当复杂的关系。