我正在尝试为此数据类型编写Eq实例:
data Tree a b = Leaf b | Node a (Tree a b) (Tree a b)
deriving (Show)
我写了一些我认为可行的简单代码:
instance Eq (Tree a b) where
(Leaf x) == (Leaf y) = x == y
(Node val1 l1 r1) == (Node val2 l2 r2) = (val1 == val2) && (l1==l2) && (r1==r2)
_ == _ = False
但后来我收到了错误:
• No instance for (Eq a) arising from a use of ‘==’
Possible fix: add (Eq a) to the context of the instance declaration
• In the first argument of ‘(&&)’, namely ‘(val1 == val2)’
In the expression: (val1 == val2) && (l1 == l2) && (r1 == r2)
In an equation for ‘==’:
(Node val1 l1 r1) == (Node val2 l2 r2)
= (val1 == val2) && (l1 == l2) && (r1 == r2)
我尝试添加Eq a => ...
,但后来我对类型b
收到了同样的错误。我似乎也无法添加Eq b
。
任何帮助将不胜感激,10倍!
答案 0 :(得分:8)
正如您所写,您必须设置类型约束Eq a
和Eq b
。您只需将约束括在括号中并用逗号分隔。
instance (Eq a, Eq b) => Eq (Tree a b) where
(Leaf x) == (Leaf y) = x == y
(Node val1 l1 r1) == (Node val2 l2 r2) = (val1 == val2) && (l1==l2) && (r1==r2)
_ == _ = False
答案 1 :(得分:6)
您编写了一个实例,您可以在(==)
和a
的实例上调用b
函数:
instance Eq (Tree a b) where
(Leaf x) == (Leaf y) = x == y
(Node val1 l1 r1) == (Node val2 l2 r2) = (val1 == val2) && (l1==l2) && (r1==r2)
_ == _ = False
但是,第一个子句中的x
和y
是a
的实例,而第二个子句中的val1
和val2
是{{1}的实例}}。 不表示你可以比较那些。例如,你不能检查两个函数的相等性(在计算机科学中根本不可能检查两个函数是否相等)。因此,在这种情况下,我们永远无法得出两棵树是否相等。
无论如何,Haskell注意到您使用函数(==) :: Eq c => c -> c -> Bool
作为操作数b
和x
(在第一个子句中),因此y
是必需的。第二个条款也有同样的推理:我们看到您使用两个Eq a
个实例调用(==)
,因此需要b
。我们需要将这些类型约束添加到Eq b
声明:
instance
因此,您只能检查两棵树的相等性,因为树的instance (Eq a, Eq b) => Eq (Tree a b) where
(Leaf x) == (Leaf y) = x == y
(Node val1 l1 r1) == (Node val2 l2 r2) = (val1 == val2) && (l1==l2) && (r1==r2)
_ == _ = False
和a
是b
类型类的实例的类型。但这是合乎逻辑的,因为如果你不能比较Eq
的值,那么你怎么能说树是否相等呢?