计算树中叶子的数量

时间:2012-10-19 18:26:28

标签: haskell tree

使用Haskell,我正在编写一个计算树中叶子总数的函数。我已经将树定义为:

data Tree a = Leaf | Node a (Tree a) (Tree a)

我通过以下方式编写了一个函数:

countL :: Tree a -> Int
countL Leaf = 1
countL (Node x tL tR) = (countL tL) + (countL tR)

这有效,但我想通过使用fold函数做同样的事情,更进一步。我有一个工作折叠功能的树,我通过这样做来定义:

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)

我试图包含fold函数(也使用了我通过这样做定义的辅助函数:

countL' :: Tree a -> Integer
countL' Leaf = 1
countL' = mytFold leafy 0 where
        leafy tL tR = tL + tR

但是我得到了一些奇怪的错误。有没有人对什么是错的有任何见解?

1 个答案:

答案 0 :(得分:5)

有两个句法/类型问题。首先,每个顶级绑定必须具有相同数量的参数,因此

countL' Leaf = ..
countL' = ..

无效。一个解决方案是

countL' Leaf = ..
countL' tree = mytFold leafy 0 tree

完成此操作后,GHC会给您一个错误,如

    Couldn't match expected type `Integer -> Integer'
                with actual type `Integer'
    Expected type: Integer -> Integer -> Integer -> Integer
      Actual type: Integer -> Integer -> Integer
    In the first argument of `mytFold', namely `leafy'
    In the expression: mytFold leafy 0 tree

这是因为mytFold需要一个3参数函数作为其第一个参数,而leafy只需要2.使用leafy _ tL tR = tL + tR修复此问题。


然而,一旦你完成了这个,你会发现这给出了错误的答案:countL' (Node 1 Leaf Leaf) == 0。一种可能使解决方案清晰的方法是删除countL' Leaf案例,并尝试将countL写为折叠。即。

countL'' = mytFold f a

您可以决定fa是什么(提示:您已经拥有f == leafy == const (+))。考虑mytFold leafy a Leaf