GHC阶段限制(模板Haskell)

时间:2012-09-29 03:18:25

标签: haskell ghc template-haskell

我无法弄清楚为什么我会在以下代码中获得“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:编辑以提供更简单的代码示例

3 个答案:

答案 0 :(得分: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) |]

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

答案 1 :(得分:1)

我不是Template Haskell的专家,但我认为r$r)的拼接必须在编译时发生,因此r必须在编译时,rfindTransforms的运行时参数。

答案 2 :(得分:0)

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

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