模板Haskell声明中的局部变量

模板Haskell声明中的局部变量,haskell,template-haskell,Haskell,Template Haskell,我正在通读,试图自己理解它,我遇到了以下部分: 回想一下,我们试图以编程方式生成格式为data Fred=Fred的声明。让我们试试准液化。由于对调用TH代码的限制,我们必须将其放在自己的模块中,因此让我们将以下内容放在Keyword.hs中,以便编译器可以找到它: module Keyword (keyword) where import Language.Haskell.TH.Syntax keyword name = [d| data $(name) = $(name) |] 现在编译

我正在通读,试图自己理解它,我遇到了以下部分:

回想一下,我们试图以编程方式生成格式为
data Fred=Fred
的声明。让我们试试准液化。由于对调用TH代码的限制,我们必须将其放在自己的模块中,因此让我们将以下内容放在Keyword.hs中,以便编译器可以找到它:

module Keyword (keyword) where

import Language.Haskell.TH.Syntax
keyword name = [d| data $(name) = $(name) |]
现在编译:

Prelude> :l Keyword.hs
[1 of 1] Compiling Keyword          ( Keyword.hs, interpreted )

Keyword.hs:6:24: parse error on input `$('
这让我想起了一件事,似乎和我最近读到的其他东西很相似:

对于动态绑定的东西(
名称
),我们可能希望它们以上下文相关的方式绑定,所以我们同样不需要名称空间。例如:

let v = mkName "T" in [| data $v = $v |]
这里我们对类型构造函数和数据构造函数使用相同的
名称

好吧,这几乎是一样的,让我们看看我是否能让它起作用:

 module Example where
 import Language.Haskell.TH
 let v = mkName "T" in [| data $v = $v |]
试一试:

 % ghc -XTemplateHaskell -c Example.hs

 Example.hs:3:25: parse error on input `data'
嗯。。。哦,也许我需要用
d
来引用声明

 let v = mkName "T" in [d| data $v = $v |]
现在:

 Example.hs:3:31: parse error on input `$v'

所以。。。。发生什么事?使用显式拼接不会改变这两种错误。我是在断章取义地使用Haskell文档模板,还是它错了?

看起来这是GHC版本早于6.12的一个bug。这个错误在GHC 7.10.1版中已修复

您是否尝试过使用-Xquasikotes?