【问题标题】:Generate dynamic Name in template haskell using the current scope使用当前范围在模板 haskell 中生成动态名称
【发布时间】:2016-05-19 21:14:59
【问题描述】:

我正在编写一个模板 haskell 拼接,并且正在努力生成正确的 Names。如果我想生成一个已知名称(例如,函数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 中有效,但是在编译时我仍然遇到同样的错误。

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

【问题讨论】:

    标签: haskell template-haskell


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢,效果很好!在我的情况下,您提到的两个问题实际上可能不是问题,因为:1)标识符也是由 TH 生成的,从相同的输入,以及 2)定义是导出的。再想一想,我突然想到我可能会合并两部分 TH 并完全摆脱这个问题......
    猜你喜欢
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    相关资源
    最近更新 更多