我想要一个 TemplateHaskell 函数 variablesInScope :: Q [Name],它返回范围内所有变量的 Name列表。TemplateHaskell 显然有这些信息可用于实现诸如 reify :: Name -> Q Info和 lookupValueName :: String -> Q (Maybe Name)之类的函数。
variablesInScope :: Q [Name]
Name
reify :: Name -> Q Info
lookupValueName :: String -> Q (Maybe Name)
我想要的函数是否存在于某个地方,而我只是忽略了它? 或者它是否可以以某种方式轻松构建?
遗憾的是,仅使用 TH无法做到这一点。
TH
但是,它需要 Q单子的 IO 特性来加载模块。
Q
请参考 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.
(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.