用foldr验证foldl的实现
我想用foldr来验证foldl是否正确:
foldl4 = foldr . flip
我在HUGS中使用了以下测试:
foldl4 (+) 3 []
foldl4 (+) 3 [1,2,3]
他们工作。
请提出更多我可以做的测试。
谢谢
这里是一个简单的测试: 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
如果你想要使用foldr
做foldl
一些提示:你应该使用foldr :: (a -> b -> b) -> b -> [a] -> b
的累加器/状态/ b部分的函数。想想继续传球并试图取代:
在
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]
作为第三个参数,则它是第一个参数, []
foldr f' b' [x,y,z] = x `f'` (y `f'` (z `f'` b'))
而你现在想要转移这些包袱
这两个不一样。 foldl
和foldr
在语义上做了不同的事情,但flip
只会导致句法上的差异,所以foldr . flip
foldr . flip
不能永远永远是foldl
。
东西是foldl
例如(有限列表)是
foldl5 = (.) (. reverse) . foldr . flip
这第一部分看起来扑朔迷离,但它主要适用reverse
的第三个参数,而不是第一个。