我正在编写模板haskell splice,并且正在努力生成正确类型的Name
。如果我想生成一个已知名称(例如,函数f
),我可以使用'f
。这需要f
在我定义拼接的范围内,而不是它所使用的位置,这正是我想要的。
现在我想要同样的东西,但对于动态名称。例如,假设我的splice以n :: Int
为参数。我想生成"f" ++ show n
作为Name
,查看拼接定义网站,而不是使用网站。
我尝试了几个选项:mkName
和lookupValueName
都要求名称在使用网站的范围内。单引号语法需要一个文字名称,而不是动态名称。
最后,我开始尝试使用mkNameG
。由于这些函数来自我使用它们的相同包,因此我从包名开始,但这会产生错误Can't find interface-file declaration for variable the-package-name:Some.Module.f0
。在一些源读取后,我找到了使用包名"main"
的地方。这似乎适用于GHCi,但在编译时我仍然会得到同样的错误。
有没有办法做到这一点?我当然可以列举所有选项,但我想避免这种情况,因为本练习的重点是使代码更具动态性。
答案 0 :(得分:1)
我想你可以通过从特定Name
'f0
中提取包名称,然后将其传递给mkNameG_v
来实现此目的。这可能不是一个好主意,原因有两个:
编写'f
检查标识符f
是否确实在范围内,而您可以将任何内容传递给mkNameG
,并且在尝试使用{Name
之前不会出错1}}以某种方式。您必须以其他方式确保仅为实际存在的标识符构建Name
,或者在使用recover
时从错误中Name
构建(除非您只是想让GHC因你看到的错误而失败。
写作'f
也算作f
的使用。未使用的未导出定义将被丢弃,因此您无法使用mkNameG
引用它们。您必须找到其他方法来确保使用"f" ++ show n
标识符。