4

我无法弄清楚为什么我在以下代码中得到“GHC 阶段限制”:

import Language.Haskell.TH

rules :: [ExpQ]
rules = [ [| \a -> a |], [| \_ -> 1 |] ]

findTransforms :: Int -> [ExpQ] -> Bool
findTransforms _ [] = False
findTransforms e (r:rs) = if ($r e) == 1 then True else findTransforms e rs

(如果代码没有提供任何有用的东西,请不要担心——为了清楚起见,它被提取的最小示例被混淆了)。

我不会从拼接代码中调用任何函数。为什么是阶段限制?

EDIT1:编辑以提供更简单的代码示例

4

3 回答 3

2

这失败的原因与您无法编写的原因相同

 eval :: ExpQ -> Int
 eval expr = $expr

因为它需要在运行时编译。

一种解决方案是通过返回嵌套表达式的表达式而不是所述表达式的值来实现findTransforms编译时。if

findTransforms :: Int -> [ExpQ] -> ExpQ
findTransforms _ []     = [| False |]
findTransforms e (r:rs) = [| if $r e == 1 then True else $(findTransforms e rs) |]

当然,这意味着你必须在你想使用它的时候拼接它。

于 2012-09-29T08:36:07.957 回答
1

我不是模板 Haskell 方面的专家,但在我看来r( $r) 的拼接必须在编译时发生,因此r必须在编译时知道,但r它是findTransforms.

于 2012-09-29T07:41:56.173 回答
0

阶段限制意味着您不能在定义模板的同一模块中使用模板 haskell。如果你把它放在一个模块中并从另一个模块调用它,你应该没问题。

Dave4420 是正确的,这是关于编译的;您的模板 haskell 必须在使用之前进行编译,因此必须在导入的模块中定义。(这意味着 ghc 在编译模块时不需要额外的传递。)

于 2012-09-29T08:04:44.077 回答