我想验证foldl的以下实现是否正确:
foldl4 = foldr . flip
我在HUGS中使用了以下测试:
foldl4 (+) 3 []
foldl4 (+) 3 [1,2,3]
他们工作了。
请建议我可以做的更多测试。
由于
答案 0 :(得分:5)
这是一个简单的测试:foldl (flip (:)) []
应为reverse
...
如果你想测试foldr
vs foldl
,你可能不应该使用交换操作;)
这是来自GHCi的一些证据:
λ> foldl (flip (:)) [] [1..5]
[5,4,3,2,1]
λ> foldl4 (flip (:)) [] [1..5]
[1,2,3,4,5]
和flip (+) = (+)
您可以直接从您的定义中猜出:
foldl4 (+) y xs
{ def }
= foldr (flip (+)) y xs
{ flip (+) = (+) }
= foldr (+) y xs
如果你想要{em>提示如何用foldl
进行foldr
:你应该使用 accumulator / state / b 部分的函数foldr :: (a -> b -> b) -> b -> [a] -> b
- 想到继续传递并尝试替换<{p>}中的:
x : (y : (z : [])
有一些智能功能来获取
((b `f` x) `f` y) `f` z
记住你想模仿
foldl f b [x,y,z] = ((b `f` x) `f` y) `f` z
foldr
基本上用:
代替它的第一个参数,[]
用它代替第二个[x,y,z]
作为第3个参数:
foldr f' b' [x,y,z] = x `f'` (y `f'` (z `f'` b'))
你现在要转移parens
答案 1 :(得分:0)
这两个不相同。 foldl
和foldr
执行语义不同的事情,但flip
只会导致语法差异,因此foldr . flip
不能永远是foldl
。
foldl
的东西(例如在有限列表上)是
foldl5 = (.) (. reverse) . foldr . flip
第一部分可能看起来令人困惑,但它基本上将reverse
应用于第三个参数而不是第一个参数。