检查Haskell中两个n-ary树是否相等

时间:2012-12-13 18:41:28

标签: haskell tree equals

我正在尝试在Haskell中实现一个简单的布尔函数来检查两个n-ary树是否相等。

我的代码是:

-- This is the n-ary tree definition.
-- (I know "Leaf a" is not necessary but I prefer to write it for clarity)
data Tree a = Leaf a | Node a [Tree a]
    deriving (Show)

-- This is a simple tree used for test purposes
t :: Tree Int
t = Node 3 [Node 5 [Leaf 11, Leaf 13, Leaf 15], Leaf 7, Leaf 9]

treeEquals :: Eq a => Tree a -> Tree a -> Bool
treeEquals (Leaf n1) (Leaf n2) = n1 == n2
treeEquals (Node n1 xs1) (Node n2 xs2) = n1 == n2 && and(zipWith (treeEquals) xs1 xs2)
treeEquals _ _ = False

我的问题是,如果我做了以下测试:

treeEquals t t
treeEquals t (Leaf 3)
treeEquals t (Node 3 [Leaf 7])

它正确返回false,因为树不相等,但如果我尝试测试,例如:

treeEquals t (Node 3 [])

它不起作用,因为它返回true,因为树是等于的。

你知道我做错了吗?

2 个答案:

答案 0 :(得分:3)

为什么不直接派生Eq并使用==

您当前代码的问题是zipWith。它会在到达较短列表的末尾时立即停止,因此zipWith treeEquals foo []始终会返回[](无论foo是什么)。

这是一个(未经测试的)替代解决方案:

treeEquals :: Eq a => Tree a -> Tree a -> Bool
treeEquals (Leaf n1) (Leaf n2) = n1 == n2
treeEquals (Node n1 xs1) (Node n2 xs2) = n1 == n2 && listTreeEquals xs1 xs2
    where
    listTreeEquals [] [] = True
    listTreeEquals (x1 : xs1) (x2 : xs2) = treeEquals x1 x2 && listTreeEquals xs1 xs2
    listTreeEquals _ _ = False
treeEquals _ _ = False

答案 1 :(得分:1)

添加另一个&&在zipWith之前检查列表的长度是否相同。