Вы пишете экземпляр, где вызываете функцию (==)
в случаях a
и b
:
instance Eq (Tree a b) where
(Leaf <b>x</b>) == (Leaf <b>y</b>) = <b>x == y</b>
(Node <b>val1</b> l1 r1) == (Node <b>val2</b> l2 r2) = (<b>val1 == val2</b>) && (l1==l2) && (r1==r2)
_ == _ = False
Но x
и y
в первом предложении являются экземплярами a
, а val1
и val2
во втором предложении - экземплярами b
. Это не сказал, что вы можете сравнить их. Например, вы не можете проверить равенство двух функций (в информатике принципиально невозможно проверить, равны ли две функции вообще). В результате в этом случае мы никогда не сможем определить, равны ли два дерева.
В любом случае, Haskell замечает, что вы используете функцию (==) :: Eq c => c -> c -> Bool
с операндами x
и y
(в первом предложении), и, следовательно, Eq a
, необходимо. То же самое относится и ко второму предложению: мы видим, что вы вызываете (==)
с двумя b
экземплярами, поэтому Eq b
требуется. Нам нужно добавить эти ограничения типа в объявление instance
:
instance <b>(Eq a, Eq b) =></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
. Но это логично, поскольку, если вы, например, не можете сравнивать значения Leaf
s, то как вы можете сказать, равно ли дерево или нет?