Haskell函数foldl(\ x y - > x * 2 + y * 2)0行为

时间:2015-05-03 21:48:13

标签: haskell fold

我遇到了问题。这两个功能有什么区别:

foldl (\x y -> x*2 + y*2) 0 [1,2,3] = 22
foldr (\x y -> x*2 + y*2) 0 [1,2,3] = 34

foldl (\x y -> x*2 + y*2) 0 [1,2,3] ⇒ f( f( f(0,1),2 ),3 )
foldr (\x y -> x*2 + y*2) 0 [1,2,3] ⇒ f( 3,f( 2, f(1,0) ) )

其中f = \x y -> x*2 + y*2

我理解foldl的结果:

x = f(0,1) = 2
y = f(x,2) = 8
z = f(y,3) = 22

但为什么foldr在每个步骤的结果之后求和?

2 + 8 + 22 = 34

2 个答案:

答案 0 :(得分:4)

您向前进行了console.log(11 > 10);评估。它应该是这样的:

foldr

相比之下,foldr f 0 [1,2,3] == f 1 (f 2 (f 3 0)) 评估(在您的问题中是正确的)看起来像

foldl

如果您认为列表foldl f 0 [1,2,3] == f (f (f 0 1) 2) 3 [1,2,3]相同,那么此1:2:3:[]图表可能有所帮助:

foldr diagram

答案 1 :(得分:2)

你对foldr的定义有点偏。而不是f( 1,f( 2, f(3,0) ) ),它应该是foldl f z [1,2,3] = ((0 `f` 1) `f` 2) `f` 3 = ((0*2 + 1*2) `f` 2) `f` 3 = (2 `f` 2) `f` 3 = (2*2 + 2*2) `f` 3 = 8 `f` 3 = 8*2 + 3*2 = 22 foldr f z [1,2,3] = 1 `f` (2 `f` (3 `f` 0)) = 1 `f` (2 `f` (3*2 + 0*2)) = 1 `f` (2 `f` 6) = 1 `f` (2*2 + 6*2) = 1 `f` 16 = 1*2 + 16*2 = 34

var applyStyling = function (element, object) {
  for(var key in object) if(object.hasOwnProperty(key)) {
    if(element.style[key] !== void 0)
      element.style[key] = object[key];
    else
      element.setAttribute(key, object[key]);
  }
}