【发布时间】:2012-12-13 18:41:28
【问题描述】:
我正在尝试在 Haskell 中实现一个简单的布尔函数来检查两个 n 元树是否相等。
我的代码是:
-- 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。
你知道我做错了什么吗?
【问题讨论】:
-
有没有更好的方法来实现这个方法而不使用 zipWith 避免两个列表遍历?
-
以这种方式使用
Leaf实际上会导致冗余表示:Node x []vsLeaf x。冗余表示通常应仅出于充分的理由使用(例如,如果它们允许某些操作更快)。在这种情况下,仅仅删除Leaf构造函数似乎是最好的做法。或者,您可以将Node构造函数更改为Node a (Tree a) [Tree a],但何必呢?