模板 Haskell 和 QuasiQuotes

什么是模板 Haskell?

模板 Haskell 是指 GHC Haskell 内置的模板元编程工具。可以在此处找到描述原始实现的文章。

什么是阶段? (或者,阶段限制是什么?)

阶段是指被执行的代码。通常,代码仅在运行时被激活,但是使用 Template Haskell,代码可以在编译时执行。 正常代码是阶段 0,编译时代码是阶段 1。

阶段限制指的是阶段 0 程序可能不会在阶段 1 执行 - 这相当于能够在编译时运行任何常规程序(不仅仅是元程序)。

按照惯例(并且为了简化实现),当前模块中的代码始终是阶段 0,并且从所有其他模块导入的代码是阶段 1.因此,只能拼接来自其他模块的表达式。

注意,阶段 1 程序是 Q ExpQ Type 等类型的阶段 0 表达; 但事实并非如此 - 并非 Q Exp 类型的每个值(第 0 阶段计划)都是第 1 阶段计划,

此外,由于拼接可以嵌套,标识符可以具有大于 1 的阶段。然后可以推广阶段限制 - 阶段 n 程序可以不在任何阶段 m> n 中执行。例如,在某些错误消息中,可以看到对大于 1 的此类阶段的引用:

>:t [| \x -> $x |]

<interactive>:1:10: error:
    * Stage error: `x' is bound at stage 2 but used at stage 1
    * In the untyped splice: $x
      In the Template Haskell quotation [| \ x -> $x |]

使用模板 Haskell 会导致不相关标识符的范围内错误?

通常,单个 Haskell 模块中的所有声明都可以被认为是相互递归的。换句话说,每个顶级声明都在单个模块中的每个其他范围内。当启用 Template Haskell 时,范围规则会发生变化 - 而是将模块分成由 TH 拼接分隔的代码组​​,每个组是相互递归的,并且每个组都在所有其他组的范围内。