使用TreeFold返回二叉树的叶子

时间:2014-06-15 19:40:33

标签: haskell tree fold

data BinTree el = EmptyBinTree
                | NonEmptyTree (BinTree el) el (BinTree el)
                  deriving (Show)

 binTreeFold :: (acc -> el -> acc -> acc) -> acc -> BinTree el -> acc
 binTreeFold _ acc EmptyBinTree = acc
 binTreeFold f acc (NonEmptyTree l n r) = f (binTreeFold f acc l) n (binTreeFold f acc r)

我在使用binTreeFold实现函数时遇到问题,该函数返回一个包含树所包含叶子的列表。我尝试过这样的事情:

leaves' :: BinTree a -> [a]
leaves' t = binTreeFold (\EmptyBinTree n EmptyBinTree -> n) [] t

但这不起作用 - 我收到此错误:

Couldn't match expected type `[a]' with actual type `BinTree t0'
    In the pattern: EmptyBinTree
    In the first argument of `binTreeFold', namely
      `(\ EmptyBinTree n EmptyBinTree -> n)'
    In the expression:
      binTreeFold (\ EmptyBinTree n EmptyBinTree -> n) [] t

我已经写了一个版本的叶子:

leaves :: BinTree a -> [a]
leaves EmptyBinTree = []
leaves (NonEmptyTree (EmptyBinTree) n (EmptyBinTree)) = [n]
leaves (NonEmptyTree l n r) = leaves l ++ leaves r

但是对于我们的作业,我们必须使用binTreeFold重写它。

leaves' :: BinTree a -> [a]
leaves' t@(NonEmptyTree (EmptyBinTree) n (EmptyBinTree)) = binTreeFold (\l n r -> [n]) [] t 
leaves' t@(NonEmptyTree l n r) = leaves' l ++ leaves' r 

我现在有类似的东西,但我不确定这是不是我应该做的,因为它与第一个功能几乎相同。

1 个答案:

答案 0 :(得分:1)

您当前的尝试有一些问题。

您获得主要点的类型错误:您编写了EmptyBinTree类型BinTree t0的模式,但传递给binTreeFold的函数应采用某种类型acc作为第一和第三个论点。

由于您将[]作为acc中的binTreeFold值传递给acc,因此[a]类型也必须是binTreeFold,即列表东西。

您也不应该尝试直接在传递给acc的函数的lambda参数中对特定值进行模式匹配 - 只需为列表指定一个名称,以便您可以在如有必要,函数的主体和模式匹配在那里。否则,该功能将在您的模式未涵盖的输入上失败。

您还需要确定函数的正确结果值是什么,请记住它也必须是(\xs n ys -> ...)类型。

因此,请将您的功能更改为...(您填写{{1}}),看看情况如何。