有没有办法在Haskell的类型类中实现约束?

Raf*_*ini 11 haskell functional-programming constraints class typeclass

是否有某种方式(任何方式)在类型类中实现约束?

作为我正在谈论的一个例子,假设我想将一个Group实现为一个类型类.如果有三个函数,那么类型将是一个组:

class Group a where
    product :: a -> a -> a  
    inverse :: a -> a 
    identity :: a
Run Code Online (Sandbox Code Playgroud)

但这些不是任何功能,但它们必须通过一些限制来联系.例如:

product a identity = a 
product a (inverse a) = identity
inverse identity = identity
Run Code Online (Sandbox Code Playgroud)

等等...

有没有办法在类的定义中强制执行这种约束,以便任何实例都会自动继承它?举个例子,假设我想实现C2组,定义如下:

 data C2 = E | C 

 instance Group C2 where
      identity = E 
      inverse C = C
Run Code Online (Sandbox Code Playgroud)

这两个定义唯一地确定C2(上述约束定义了所有可能的操作 - 实际上,由于约束,C2是唯一可能具有两个元素的组).有没有办法让这项工作?

Nor*_*sey 11

有没有办法强制执行这种约束?

不是 很多人一直在要求它,包括杰出的Tony Hoare,但是现在还没有出现.

这个问题对于Haskell Prime小组来说是一个很好的讨论话题.如果有人提出了一个好的建议,可能会在那里找到.

PS这是一个重要的问题!


Pau*_*son 8

在某些情况下,您可以使用QuickCheck指定属性.这不是完全强制执行,但它允许您提供所有实例应该通过的通用测试.例如,对于Eq,您可能会说:

prop_EqNeq x y = (x == y) == not (x != y)
Run Code Online (Sandbox Code Playgroud)

当然,实例作者仍然需要调用此测试.

为monad法律做这件事会很有趣.


Dar*_*rio 5

类类可以包含定义和声明.例:

class Equality a where
    (?=), (!=) :: a -> a -> Bool

    a ?= b = not (a != b)
    a != b = not (a ?= b)

instance Eq a => Equality a where
    (?=) = (==)

test = (1 != 2)
Run Code Online (Sandbox Code Playgroud)

您还可以在普通的Haskell中指定特殊约束(让我们称之为法则),但不能保证编译器会使用它们.一个常见的例子是一元法则