给定这个定义,我如何为通用 Haskell 树编写通用的 foldr 和 foldl 函数?
data (Eq a, Show a) => Tree a = Void | Node a [Tree a]
deriving (Eq, Show)
treefoldr :: (Eq a, Show a) =>
(a -> b -> c) -> c -> (c -> b -> b) -> b -> Tree a -> c
treefoldl :: (Eq a, Show a) =>
(b -> a -> c) -> c -> (c -> b -> b) -> b -> Tree a -> c
即使我能理解 foldr 和 foldl 函数在 Haskell 中的工作原理,我也不太确定如何为树编写这个通用函数。
编辑:我尝试过这样的事情(甚至没有编译):
treefoldr _ g1 _ _ Void = g1
treefoldr f1 g1 f2 g2 (Node a ts) = f1 a (foldr f2 g2 ts)
编辑2:再试一次......
treefoldr _ z1 _ _ Void = z1
treefoldr f z1 g z2 (Node a ts) =
f a (foldr g z2 (map (\x -> treefoldr f z1 g z2 x) ts))
treefoldl _ z1 _ _ Void = z1
treefoldl f z1 g z2 (Node a ts) =
f (foldl g z2 (map (\x -> treefoldl f z1 g z2 x) ts)) a
treefoldr
正在工作,但treefoldl
不是:
Couldn't match expected type `c' against inferred type `b' `c' is a rigid type variable bound by the type signature for `treefoldl' at trees.hs:47:42 `b' is a rigid type variable bound by the type signature for `treefoldl' at trees.hs:47:32 In the first argument of `foldl', namely `g' In the first argument of `f', namely `(foldl g z2 (map (\ x -> treefoldl f z1 g z2 x) ts))' In the expression: f (foldl g z2 (map (\ x -> treefoldl f z1 g z2 x) ts)) a