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

Generate dynamic Name in template haskell using the current scope

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

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

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

最后我开始尝试 mkNameG。由于这些函数与我在其中使用的函数来自同一个包,因此我从包名开始,但这给出了错误 Can't find interface-file declaration for variable the-package-name:Some.Module.f0。在阅读了一些源代码之后,我找到了使用包名 "main" 的地方。这似乎在 GHCi 中有效,但在编译时我仍然遇到同样的错误。

有什么办法吗?我当然可以列举所有的选项,但我想避免这种情况,因为这个练习的重点是让代码更动态。

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

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

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