Is there some way (any way) to implement constraints in type classes?
是否有某种方式(任何方式)在类型类中实现约束?
As an example of what I'm talking about, suppose I want to implement a Group as a type class. So a type would be a group if there are three functions:
作为我正在谈论的一个例子,假设我想将一个Group实现为一个类型类。如果有三个函数,那么类型将是一个组:
class Group a where
product :: a -> a -> a
inverse :: a -> a
identity :: a
But those are not any functions, but they must be related by some constraints. For example:
但这些不是任何功能,但必须通过一些限制来关联。例如:
product a identity = a
product a (inverse a) = identity
inverse identity = identity
etc...
等等...
Is there a way to enforce this kind of constraint in the definition of the class so that any instance would automatically inherit it? As an example, suppose I'd like to implement the C2 group, defined by:
有没有办法在类的定义中强制执行这种约束,以便任何实例都会自动继承它?举个例子,假设我想实现C2组,定义如下:
data C2 = E | C
instance Group C2 where
identity = E
inverse C = C
This two definitions uniquely determines C2 (the constraints above define all possible operations - in fact, C2 is the only possible group with two elements because of the constraints). Is there a way to make this work?
这两个定义唯一地确定C2(上面的约束定义了所有可能的操作 - 事实上,由于约束,C2是唯一可能具有两个元素的组)。有没有办法让这项工作?
3 个解决方案
#1
11
Is there a way to enforce this kind of constraint?
有没有办法强制执行这种约束?
No. Lots of people have been asking for it, including the illustrious Tony Hoare, but nothing appears on the horizon yet.
没有。许多人一直在要求它,包括杰出的Tony Hoare,但现在还没有出现。
This problem would be an excellent topic of discussion for the Haskell Prime group. If anyone has floated a good proposal, it is probably to be found there.
这个问题对于Haskell Prime小组来说是一个很好的讨论话题。如果有人提出了一个好的建议,可能会在那里找到。
P.S. This is an important problem!
附:这是一个重要的问题!
#2
8
In some cases you can specify the properties using QuickCheck. This is not exactly enforcement, but it lets you provide generic tests that all instances should pass. For instance with Eq you might say:
在某些情况下,您可以使用QuickCheck指定属性。这不是完全强制执行,但它允许您提供所有实例应传递的通用测试。例如,对于Eq,您可能会说:
prop_EqNeq x y = (x == y) == not (x != y)
Of course it is still up to the instance author to call this test.
当然,实例作者仍然需要调用此测试。
Doing this for the monad laws would be interesting.
为monad法律做这件事会很有趣。
#3
5
Type classes can contain definitions as well as declarations. Example:
类型类可以包含定义和声明。例:
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)
You can also specify special constraints (let's call them laws) in plain Haskell, but it's not guaranteed that the compiler will use them. A common example are monadic laws
您还可以在普通的Haskell中指定特殊约束(让我们称之为法则),但不能保证编译器会使用它们。一个常见的例子是一元法则
#1
11
Is there a way to enforce this kind of constraint?
有没有办法强制执行这种约束?
No. Lots of people have been asking for it, including the illustrious Tony Hoare, but nothing appears on the horizon yet.
没有。许多人一直在要求它,包括杰出的Tony Hoare,但现在还没有出现。
This problem would be an excellent topic of discussion for the Haskell Prime group. If anyone has floated a good proposal, it is probably to be found there.
这个问题对于Haskell Prime小组来说是一个很好的讨论话题。如果有人提出了一个好的建议,可能会在那里找到。
P.S. This is an important problem!
附:这是一个重要的问题!
#2
8
In some cases you can specify the properties using QuickCheck. This is not exactly enforcement, but it lets you provide generic tests that all instances should pass. For instance with Eq you might say:
在某些情况下,您可以使用QuickCheck指定属性。这不是完全强制执行,但它允许您提供所有实例应传递的通用测试。例如,对于Eq,您可能会说:
prop_EqNeq x y = (x == y) == not (x != y)
Of course it is still up to the instance author to call this test.
当然,实例作者仍然需要调用此测试。
Doing this for the monad laws would be interesting.
为monad法律做这件事会很有趣。
#3
5
Type classes can contain definitions as well as declarations. Example:
类型类可以包含定义和声明。例:
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)
You can also specify special constraints (let's call them laws) in plain Haskell, but it's not guaranteed that the compiler will use them. A common example are monadic laws
您还可以在普通的Haskell中指定特殊约束(让我们称之为法则),但不能保证编译器会使用它们。一个常见的例子是一元法则