Haskell 约束不小于实例头 [英] Haskell Constraint is no smaller than the instance head
问题描述
有些戒指可以配备规范功能:
Some rings can be equipped with a norm function:
class (Ring.C a) => EuclideanDomain a where
norm :: a -> Integer
有了这个功能,戒指的排序就很明显了:
With this function, the ring can be ordered in the obvious way:
compare x y = compare (norm x) (norm y)
但我不知道如何表明这一点.我试着做
But I'm not sure how to indicate this. I tried to do
instance (EuclideanDomain a, Eq a) => Ord a where
但这给了我一些警告,当我启用相关的编译器标志时,它告诉我约束不小于实例头" - 如果我启用 UndecidableInstances,一切都会变得糟糕.
but this gives me some warnings, and when I enable the relevant compiler flags it tells me "Constraint is no smaller than the instance head" - if I enable UndecidableInstances everything goes to hell.
有没有办法做我想做的事?
Is there a way to do what I want?
推荐答案
hammar's 已经提供了解决方案;我想指出这个例子的另一个问题.你想表达的是当一个类型是Eq
和EuclideanDomain
的实例时,用这个规则为Ord
创建一个实例."但这在 Haskell 中是无法表达的.线
hammar's already provided a solution; I'd like to point out another problem with this example. What you want to express is "Whenever a type is an instance of Eq
and EuclideanDomain
, use this rule to make an instance for Ord
." But this is inexpressible in Haskell. The line
instance (EuclideanDomain a, Eq a) => Ord a where
实际上的意思是,使用此规则为任何类型创建 Ord
实例.如果 EuclideanDomain
和 Eq
的实例不是不在范围内".这不太好,因为这条规则会与所有其他 Ord 实例重叠.
actually means, "Use this rule to make an Ord
instance for any type. It's an error if instances of EuclideanDomain
and Eq
aren't in scope". That's not good, because this rule will overlap with every other Ord instance.
基本上任何时候你想写一个实例Class typevar
,你都需要一个新类型.
Basically any time you want to write an instance Class typevar
, you're going to need a newtype.
这篇关于Haskell 约束不小于实例头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!