Haskell二叉树顺序折叠

问题描述

我定义了我的数据类型 BinTree,它描述了我的二叉树:

data BinTree a = Empty | Node a (BinTree a) (BinTree a) deriving (Show,Eq)

之后,我为二叉树实现了三个排序函数preorderinorderpostorder

preorder :: BinTree a -> [a]
preorder Empty = []
preorder (Node x lt rt) = [x] ++ preorder lt ++ preorder rt

inorder :: BinTree  a -> [a]
inorder Empty = []
inorder (Node x lt rt) = inorder lt ++ [x] ++ inorder rt

postorder :: BinTree a -> [a]
postorder Empty = []
postorder (Node x lt rt) = postorder lt ++ postorder rt ++ [x]

为了改进我的订单函数,我实现了 foldTree 函数(它作为普通的 foldr 函数工作,但使用二叉树):

foldTree :: (a -> b -> b -> b) -> b -> BinTree -> b
    foldTree f e Empty = e
    foldTree f e (Node x lt rt) = f x (foldTree f e lt) (foldTree f e rt)

现在我陷入了困境,因为我不知道如何将订单函数foldTree 结合起来。

有人可以给我一个提示吗?

解决方法

如果“组合”是指使用最后一个实现三个函数中的每一个,那么这个 JSFiddle 似乎很有用,例如

preorder  t  =  foldTree (\a l r -> (a :) . l . r) id t []
inorder   t  =  foldTree (\a l r -> l . (a :) . r) id t []
postorder t  =  foldTree (\a l r -> l . r . (a :)) id t []

尝试一下:

> t = Node 1 (Node 2 Empty (Node 3 Empty Empty)) (Node 4 (Node 5 Empty Empty) Empty)
{-
                 1
        2                 4
     .      3         5       .
          .   .     .   .
-}

> inorder t
[2,3,1,5,4]

> preorder t
[1,2,4,5]

> postorder t
[3,1]

函数的正确类型当然是

foldTree :: (a -> b -> b -> b) -> b -> BinTree a -> b
--                                            ^^^