使用当前范围在模板haskell中生成动态名称

时间:2016-05-18 14:17:53

标签: haskell template-haskell

我正在编写模板haskell splice,并且正在努力生成正确类型的Name。如果我想生成一个已知名称(例如,函数f),我可以使用'f。这需要f在我定义拼接的范围内,而不是它所使用的位置,这正是我想要的。

现在我想要同样的东西,但对于动态名称。例如,假设我的splice以n :: Int为参数。我想生成"f" ++ show n作为Name,查看拼接定义网站,而不是使用网站。

我尝试了几个选项:mkNamelookupValueName都要求名称在使用网站的范围内。单引号语法需要一个文字名称,而不是动态名称。

最后,我开始尝试使用mkNameG。由于这些函数来自我使用它们的相同包,因此我从包名开始,但这会产生错误Can't find interface-file declaration for variable the-package-name:Some.Module.f0。在一些源读取后,我找到了使用包名"main"的地方。这似乎适用于GHCi,但在编译时我仍然会得到同样的错误。

有没有办法做到这一点?我当然可以列举所有选项,但我想避免这种情况,因为本练习的重点是使代码更具动态性。

1 个答案:

答案 0 :(得分:1)

我想你可以通过从特定Name 'f0中提取包名称,然后将其传递给mkNameG_v来实现此目的。这可能不是一个好主意,原因有两个:

  • 编写'f检查标识符f是否确实在范围内,而您可以将任何内容传递给mkNameG,并且在尝试使用{Name之前不会出错1}}以某种方式。您必须以其他方式确保仅为实际存在的标识符构建Name,或者在使用recover时从错误中Name构建(除非您只是想让GHC因你看到的错误而失败。

  • 写作'f也算作f的使用。未使用的未导出定义将被丢弃,因此您无法使用mkNameG引用它们。您必须找到其他方法来确保使用"f" ++ show n标识符。