Using Haskell, I’m writing a function that counts the total number of leaves in a tree. I have defined the tree as so:
data Tree a = Leaf | Node a (Tree a) (Tree a)
I writing a function that does this by:
countL :: Tree a -> Int
countL Leaf = 1
countL (Node x tL tR) = (countL tL) + (countL tR)
This works but I want to take it a step further by doing the same thing using the fold function. I’ve having a working fold function for trees that I defined by doing:
mytFold :: (a -> b -> b -> b) -> b -> Tree a -> b
mytFold f g Leaf = g
mytFold f g (Node a xl xr) = f a (mytFold f g xl) (mytFold f g xr)
I tried to include the fold function (also used a helper function that I defined by doing this:
countL' :: Tree a -> Integer
countL' Leaf = 1
countL' = mytFold leafy 0 where
leafy tL tR = tL + tR
But I’m getting some weird errors. Does anyone have any insight on what’s wrong?
There are two syntactic/type problems. Firstly, every top level binding must have the same number of arguments, so
isn’t valid. One solution is
Once you’ve done this, then GHC gives you an error like
Which is because
mytFoldrequires a 3-argument function as its first argument, andleafyjust takes 2. Fix this by usingleafy _ tL tR = tL + tR.However, once you have done this, you will see that this gives the wrong answer:
countL' (Node 1 Leaf Leaf) == 0. A way that might make the solution clear is to removing thecountL' Leafcase, and trying to writecountLas just the fold. i.e.where you have do decide what
fandaare (hint: you already havef == leafy == const (+)). ConsidermytFold leafy a Leaf.