我正在尝试在Haskell中为我的树数据类型创建一个Eq(树a)实例,以便如果两个树具有相同的元素,则它们是相等的。所以我有一种方法可以将我的树变成一个列表(展平),然后比较排序后的列表。 但是我遇到错误,例如对列表进行排序时没有(Ord a)实例,或者当我==我的两个列表时没有(Eq a)实例。
import Data.List as L
data Tree a = EmptyTree | Node (Tree a) a (Tree a)
instance Eq (Tree a) where
(==) t1 t2 = L.sort(flatten t1) == L.sort(flatten t2)
flatten :: Tree a -> [a]
flatten EmptyTree = []
faltten (Node x1 y x2) = [y] ++ (flatten x1) ++ (flatten x2)
我不知道为什么它拒绝编译。我使用了一种方法,该方法从列表中生成一棵树,然后展平该树返回原始列表,因此我知道Flatten正常工作。我假设它正在抱怨不知道列表的内容是Ord还是Eq,但是我不知道如何解决此问题。添加
(Ord a, Eq a) =>
平展签名没有做到。
答案 0 :(得分:11)
问题不是{em> flatten
:flatten
不需要元素是可排序的,它只是生成元素列表。
问题是您在(==)
的实现中使用sort :: Ord a => [a] -> [a]
,因此sort
需要列表中的元素属于{{ 1}}类型类。
元素的类型也必须是Ord
类型类的成员,因为您随后在列表上调用了Eq
。但是,由于(==)
暗示着Ord
,因此在这里并不是真正的问题。
因此,我们需要将这些类型约束添加到Eq
声明中:
instance
因此,在给定的树包含类型为instance Ord a => Eq (Tree a) where
(==) t1 t2 = L.sort(flatten t1) == L.sort(flatten t2)
类型类实例的元素的情况下,我们只能检查两棵树是否相等。