声明一个等式(树a)的实例,其中如果两个树具有相同的元素,则它们相等

时间:2018-12-30 12:41:17

标签: haskell types tree

我正在尝试在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) => 

平展签名没有做到。

1 个答案:

答案 0 :(得分:11)

问题不是{em> flattenflatten不需要元素是可排序的,它只是生成元素列表。

问题是您在(==)的实现中使用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)类型类实例的元素的情况下,我们只能检查两棵树是否相等。