【发布时间】:2018-09-21 22:54:24
【问题描述】:
给定一棵树定义为:
data Tree a = Leaf | Node (Tree a) a (Tree a) deriving (Eq, Show)
我要使用该功能:
foldTree :: (b -> a -> b -> b) -> b -> Tree a -> b
foldTree _ b Leaf = b
foldTree f b (Node lt x rt) = f (foldTree f b lt) x (foldTree f b rt)
为了能够创建普通foldr 和foldl 的等效项:
foldTreeR :: (a -> b -> b) -> b -> Tree a -> b
foldTreeL :: (b -> a -> b) -> b -> Tree a -> b
我认为这些会相当简单,因为它们的定义几乎完全模仿了 foldr 和 foldl 的定义。我假设我所要做的就是以类似的方式插入值,所以我会编写一个匿名函数,一个带有我的树的基本状态和需要处理的树的累加器。 lambda 函数必须根据所执行的折叠类型而有所不同。
这是我想出的:
foldTreeR :: (a -> b -> b) -> b -> Tree a -> b
foldTreeR f acc t = foldTree (\x acc -> f x acc) acc t
我得到错误:
Couldn't match type ‘a’ with ‘a -> b’ ‘a’ is a rigid type variable bound by the type signature for: foldTreeR :: forall a b. (a -> b -> b) -> b -> Tree a -> b at Folds.hs:294:14 Expected type: Tree (a -> b) Actual type: Tree a
我不确定在这种情况下我应该如何传递原始树。
似乎左折叠只是一个变体,lambda函数中的值重新排序以及评估不同。
有人可以帮助我了解如何在这里找到解决方案吗?
【问题讨论】:
-
foldTree :: (b -> a -> b -> b) -> b -> Tree a -> b期望第一个参数是一个接受 3 个参数的函数。你给了它一个带有 2 个参数的函数。基本上错误说它不能使一个值(f x acc的结果)成为一个函数(b -> a -> (b -> b)类型的函数的预期结果,相当于b -> a -> b -> b) -
我明白这一点,但我不完全确定在这种情况下我会作为第三个值传递什么。首先是它自己的树的值,其次是累加器。第三个可能在这里?
标签: haskell functional-programming binary-tree fold