模板haskell中的数据构造函数 [英] Data constructor in template haskell

查看:97
本文介绍了模板haskell中的数据构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建Z / n戒指(与普通算术一样,但是以某个整数为模)。一个示例实例是Z4:

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

在环上。我希望能够快速生成这些东西,而且我认为使用模板haskell的方法就是这样。理想情况下,我想只是去 $(makeZ 4),并且它会为 Z4 定义如上。



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



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

解决方案

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


拼接可以代替

p>


  • 表达式;拼接表达式的类型必须为 Q Exp

  • ;拼接表达式必须包含 Q Typ

  • 顶级声明列表;拼接表达式必须包含类型 Q [Dec]


然而,在 $ n 这两个事件中,您试图拼接名称



这意味着你不能使用报价和接头来做到这一点。您必须使用 Language.Haskell.TH 模块中提供的各种组合器来构建声明。



I

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

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

  $(genData(mkNameZ5))


I'm trying to create the ring Z/n (like normal arithmetic, but modulo some integer). An example instance is Z4:

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

And so on for the ring. I'd like to be able to quickly generate these things, and I think the way to do it is with template haskell. Ideally I'd like to just go $(makeZ 4) and have it spit out the code for Z4 like I defined above.

I'm having a lot of trouble with this though. When I do genData n = [d| data $n = $n Integer] I get "parse error in data/newtype declaration". It does work if I don't use variables though: [d| data Z5 = Z5 Integer |], which must mean that I'm doing something weird with the variables. I'm not sure what though; I tried constructing them via newName and that didn't seem to work either.

Can anyone help me with what's going on here?

解决方案

The Template Haskell documentation lists the things you are allowed to splice.

A splice can occur in place of

  • an expression; the spliced expression must have type Q Exp
  • an type; the spliced expression must have type Q Typ
  • a list of top-level declarations; the spliced expression must have type Q [Dec]

In both occurrences of $n, however, you're trying to splice a name.

This means you can't do this using quotations and splices. You'll have to build declaration using the various combinators available in the Language.Haskell.TH module.

I think this should be equivalent to what you're trying to do.

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

Yep, it's a bit ugly, but there you go. To use this, call it with a fresh name, e.g.

$(genData (mkName "Z5"))

这篇关于模板haskell中的数据构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆