在Haskell中,有什么方法可以用多种方式表示一个类型应该是一个类型类的实例吗? [英] In Haskell, is there any way to express that a type should be an instance of a typeclass in more than one way?

查看:105
本文介绍了在Haskell中,有什么方法可以用多种方式表示一个类型应该是一个类型类的实例吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



有没有一种方法可以表达一个类型应该以多种方式成为一个类型类的实例?这可以用一个例子来说明(这可能有点愚蠢):在数学中,我们可以说半环是一个集合,它是一个操作下的一个交换幺半群(我们称之为加法,标识为0)和一个幺半群另一个(我们称之为乘法)以及乘法在加法中分配的要求以及零乘法下所有元素的湮灭。后面的部分在这里并不重要。

现在假设我有一个类型类 Monoid (不要与 Data混淆。 Monoid ),

  class Monoid m其中
单元:: m
operation :: m - > m - > m

并希望创建一个类型类型 Semiring 。根据上面给出的定义,我想说如果r类型是两种( distinct )方式的幺半群,我们将称它为半环。所以我想要一些像

  class(Monoid r,Monoid r)=> Semiring r where ... 

这当然不起作用。无可否认,这个例子变得有点奇怪,因为我们不希望半环节需要更多的函数,所以类型类将是空的,但我希望它能说明我所问的(或者假设我们需要某个函数 f:r-> r 用于半成品r )。



因此,在常规设置中,我问:给定一个类型类型 A ,有没有办法参数化一个类型类型 B a ,要求 a 以两种方式( A ) c $ c> a 应该以两种方式实现由 A 指定的函数)?

 <$ c $一个选项是为semiring的两个操作定义自己的monoids: c> class AdditiveMonoid m其中
zero :: m
(< +>):: m - > m - > m

class MultiplicativeMonoid m其中
one :: m
(< *>):: m - > m - > m

然后合并它们:

  class(MultiplicativeMonoid m,AdditiveMonoid m)=>半环m 

问题是你不能表达幺半律或一个操作是可交换的事实。您可以获得的最好方式是为法律定义quickcheck属性。



对于某些灵感,请检查 numeric prelude and 这篇论文。

(Sorry in advance if the question is stupid or obvious -- I don't have a lot of experience with Haskell).

Is there a way to express that a type should be an instance of a typeclass in more than one way? This is best illustrated with an example (which is probably somewhat silly): In mathematics, we can say that a semiring is a set that is a commutative monoid under one operation (which we'll call addition, identity 0) and a monoid under another (which we'll call multiplication) along with the requirements that multiplication distributes over addition and that 0 annihilates all elements under multiplication. The latter parts aren't important here.

Suppose now that I have a typeclass Monoid (not to be confused with Data.Monoid),

class Monoid m where
    unit :: m 
    operation :: m -> m -> m

and would like to create a typeclass Semiring. From the definition given above, I'd like to say "if the type r is a monoid in two (distinct) ways, we'll call it semiring". So I'd like something like

class (Monoid r, Monoid r) => Semiring r where ...

which of course doesn't work. Admittedly, the example becomes a bit strange since there are no more functions we'd like to require for semirings, so the typeclass would be empty, but I hope it illustrates what I'm asking about (or just pretend that we require some function f:r->r for Semiring r).

So, in the general setting, I'm asking: Given a typeclass A, is there a way to parametrize a typeclass B a with the requirement that a be an instance of A in two ways (meaning that a should implement the functions specified by A in two ways)?

解决方案

One option is to define your own monoids for the two operations of a semiring:

class AdditiveMonoid m where
    zero :: m
    (<+>) :: m -> m -> m

class MultiplicativeMonoid m where
    one :: m
    (<*>) :: m -> m -> m

and then combine them:

class (MultiplicativeMonoid m, AdditiveMonoid m) => Semiring m

The problem is that you cannot express the monoid laws or the fact that one operation is commutative. The best you can get is defining quickcheck properties for the laws.

For some inspiration check the numeric prelude and this paper.

这篇关于在Haskell中,有什么方法可以用多种方式表示一个类型应该是一个类型类的实例吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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