模板haskell中的数据构造函数

时间:2011-09-27 01:00:10

标签: haskell template-haskell

我正在尝试创建环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构建它们,但似乎也没有用。

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

1 个答案:

答案 0 :(得分:13)

Template Haskell documentation列出了您允许拼接的内容。

  

可以用拼接代替

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

但是,在$n的两次出现中,您都试图拼接名称

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

我认为这应该等同于你要做的事情。

genData :: Name -> Q [Dec]
genData n = fmap (:[]) $ dataD (cxt []) n []
                           [normalC n [strictType notStrict [t| Integer |]]] []
是的,它有点难看,但你去了。要使用此功能,请使用新名称进行调用,例如

$(genData (mkName "Z5"))