Как мне написать обобщенную функцию foldr и foldl для общих деревьев Haskell, учитывая это определение?
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