I am trying to implement a simple boolean function in Haskell to check if two n-ary trees are equal.
My code is:
-- 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
My problem is that if I do tests such as:
treeEquals t t
treeEquals t (Leaf 3)
treeEquals t (Node 3 [Leaf 7])
it returns correctly false because the trees are not equal, but if I try a test such as:
treeEquals t (Node 3 [])
It doesn't work because it returns true as the trees were equals.
Do you know what I am doing wrong?
Leafin this fashion actually leads to redundant representations:Node x []vsLeaf x. Redundant representations should normally be used only for a good reason (e.g., if they allow some operations to be much faster). In this case, just dropping theLeafconstructor seems likely to be the best course of action. Alternatively, you could change theNodeconstructor toNode a (Tree a) [Tree a], but why bother?