Haskell - 编译错误

时间:2015-03-13 19:25:04

标签: haskell compiler-errors

data Set a = Set [a]
member xs x = elem x xs
subset xs ys = and (map (member ys) xs)

instance (Eq a) => Eq (Set a) where  
  (Set xs) == (Set ys) = (subset xs ys) && (subset ys xs)

class Ord a => Comparable a where
  cmp :: a -> a -> String
  cmp x y
    | x == y    = "eq"
    | otherwise = "neq"

instance Comparable a => Comparable (Set a) where
  cmp (Set xs) (Set ys)
    | (Set xs) == (Set ys) = "same"
    | otherwise            = "different"  

我收到以下错误:

无法演绎(Ord(Set a))   来自实例声明的超类 从上下文(可比较的a)   由'Comparable(Set a)'

的实例声明绑定

我想知道错误是什么? 感谢。

3 个答案:

答案 0 :(得分:1)

ComparableOrd的子类,因此您需要为Ord (Set a)添加一个实例,例如:

instance Ord a => Ord (Set a) where
  compare (Set s1) (Set s2) =
    compare (sort s1) (sort s2)

答案 1 :(得分:1)

此声明

class Ord a => Comparable a where

声明类Comparable的每个成员都必须是类Ord的成员。如果我要尝试

data MyType = ...
instance Comparable MyType where
  cmp x y = "hello"

编译器会抱怨缺少实例Ord MyType。我没有使用Ord实例中的任何内容并不重要:Comparable的定义需要它。

要解决此问题,请添加实例

instance Ord a => Ord (Set a) where
   compare setA setB = ....

之后,如果您向约束添加Comparable,则可以使用Ord a实例。

instance (Ord a , Comparable a) => Comparable (Set a) where
  cmp (Set xs) (Set ys)
    | (Set xs) == (Set ys) = "same"
    | otherwise            = "different"  

答案 2 :(得分:0)

您为设置数据类型提供了Equality实例,但它没有Ord实例。当您尝试创建Comparable类的Set和实例时,它要求Set必须是Ord的实例。