使用当前范围在模板 haskell 中生成动态名称
Generate dynamic Name in template haskell using the current scope
我正在编写模板 haskell 拼接,并且正在努力生成正确的 Name
类型。如果我想生成一个已知的名称(比如,一个函数 f
),我可以使用 'f
。这要求 f
在我定义拼接的范围内,而不是在使用它的范围内,这正是我想要的。
现在我想要同样的东西,但要一个动态名称。例如,假设我的拼接采用 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 中有效,但在编译时我仍然遇到同样的错误。
有什么办法吗?我当然可以列举所有的选项,但我想避免这种情况,因为这个练习的重点是让代码更动态。
我想您可以通过从特定的 Name
'f0
中提取包名称,然后将其传递给 mkNameG_v
来完成此操作。这可能不是一个好主意,原因有二:
编写 'f
检查标识符 f
是否确实在范围内,而您可以将任何内容传递给 mkNameG
并且在您尝试之前不会收到错误以某种方式使用 Name
。您必须以其他方式确保只为实际存在的标识符构建 Name
,或者在使用 Name
时从错误中构建 recover
(除非您只想让 GHC 因您看到的错误而失败)。
写'f
也算作f
的使用。未使用的未导出定义将被简单地丢弃,因此您将无法使用 mkNameG
引用它们。您将不得不找到其他方法来确保使用您的 "f" ++ show n
标识符。
我正在编写模板 haskell 拼接,并且正在努力生成正确的 Name
类型。如果我想生成一个已知的名称(比如,一个函数 f
),我可以使用 'f
。这要求 f
在我定义拼接的范围内,而不是在使用它的范围内,这正是我想要的。
现在我想要同样的东西,但要一个动态名称。例如,假设我的拼接采用 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 中有效,但在编译时我仍然遇到同样的错误。
有什么办法吗?我当然可以列举所有的选项,但我想避免这种情况,因为这个练习的重点是让代码更动态。
我想您可以通过从特定的 Name
'f0
中提取包名称,然后将其传递给 mkNameG_v
来完成此操作。这可能不是一个好主意,原因有二:
编写
'f
检查标识符f
是否确实在范围内,而您可以将任何内容传递给mkNameG
并且在您尝试之前不会收到错误以某种方式使用Name
。您必须以其他方式确保只为实际存在的标识符构建Name
,或者在使用Name
时从错误中构建recover
(除非您只想让 GHC 因您看到的错误而失败)。写
'f
也算作f
的使用。未使用的未导出定义将被简单地丢弃,因此您将无法使用mkNameG
引用它们。您将不得不找到其他方法来确保使用您的"f" ++ show n
标识符。