模板haskell中的数据构造函数

Xod*_*rap 11 haskell template-haskell

我正在尝试创建环Z/n(像普通算术一样,但模数为整数).一个示例实例是Z4:

instance Additive.C Z4 where
  zero = Z4 0
  (Z4 x) + (Z4 y) = Z4 $ (x + y) `mod` 4
Run Code Online (Sandbox Code Playgroud)

对于戒指等等.我希望能够快速生成这些东西,我认为这样做的方法是使用模板haskell.理想情况下,我只是想让$(makeZ 4)Z4像上面定义的那样吐出代码.

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

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

ham*_*mar 13

模板哈斯克尔文件列出了允许拼接的事情.

可以用拼接代替

  • 一种表达; 拼接表达式必须具有类型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 |]]] []
Run Code Online (Sandbox Code Playgroud)

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

$(genData (mkName "Z5"))
Run Code Online (Sandbox Code Playgroud)