11

我正在尝试创建环 Z/n (就像普通算术一样,但是以某个整数为模)。一个例子是 Z4:

instance Additive.C Z4 where
  zero = Z4 0
  (Z4 x) + (Z4 y) = Z4 $ (x + y) `mod` 4

以此类推。我希望能够快速生成这些东西,我认为这样做的方法是使用模板 haskell。理想情况下,我只想$(makeZ 4)让它吐出Z4我上面定义的代码。

不过,我在这方面遇到了很多麻烦。当我这样做时,genData n = [d| data $n = $n Integer]我得到“数据/新类型声明中的解析错误”。如果我不使用变量,它确实有效:[d| data Z5 = Z5 Integer |],这一定意味着我对变量做了一些奇怪的事情。我不确定是什么;我尝试通过 newName 构建它们,但这似乎也不起作用。

任何人都可以帮我解决这里发生的事情吗?

4

1 回答 1

13

模板 Haskell 文档列出了允许拼接的内容。

拼接可以代替

  • 一种表达; 拼接的表达式必须有类型Q Exp
  • 一种类型;拼接的表达式必须有类型Q Typ
  • 顶级声明列表;拼接的表达式必须有类型Q [Dec]

但是,在这两种情况下$n,您都在尝试拼接name

这意味着您不能使用引号和拼接来执行此操作。您必须使用Language.Haskell.TH模块中可用的各种组合器来构建声明。

我认为这应该等同于您正在尝试做的事情。

genData :: Name -> Q [Dec]
genData n = fmap (:[]) $ dataD (cxt []) n []
                           [normalC n [strictType notStrict [t| Integer |]]] []

是的,它有点难看,但你去。要使用它,请用新名称调用它,例如

$(genData (mkName "Z5"))
于 2011-09-27T01:35:41.157 回答