Haskell vs. erlang:foldl 的区别?
Haskell vs. erlang: difference in foldl?
我注意到 Haskell 和 Erlang 在 foldl
方面存在差异。
对于 foldr
,两种语言 return 相同的结果:
foldr (\x y -> 2*x+y) 4 [1, 2, 3] -- returns 49
lists:foldr(fun(X, Y) −> X+2∗Y end, 4, [1,2,3]). % returns 49
但是 foldl
的 return 值不同:
foldl (\x y -> x+2*y) 4 [1, 2, 3] -- returns 16
lists:foldl(fun(X, Y) −> X+2∗Y end, 4, [1,2,3]). -- returns 43
如何解释这种差异?
您没有简化折叠函数,这让您感到困惑。
左折,Haskell:
Prelude Debug.Trace> foldl (\x y -> trace("x:"++show x++" y:"++show y) $ x+y) 4 [1,2,3]
x:4 y:1
x:5 y:2
x:7 y:3
10
左折,Erlang:
1> lists:foldl(fun (X,Y) -> io:format("x:~p y:~p~n", [X,Y]), X+Y end, 4, [1,2,3]).
x:1 y:4
x:2 y:5
x:3 y:7
10
右折,Haskell:
Prelude Debug.Trace> foldr (\x y -> trace("x:"++show x++" y:"++show y) $ x+y) 4 [1,2,3]
x:3 y:4
x:2 y:7
x:1 y:9
10
右折,Erlang:
2> lists:foldr(fun (X,Y) -> io:format("x:~p y:~p~n", [X,Y]), X+Y end, 4, [1,2,3]).
x:3 y:4
x:2 y:7
x:1 y:9
10
由此可见,在Haskell中,foldl
函数将被传递(Accumulator, Element)
,而foldr
函数将被传递(Element, Accumulator)
。另一方面,Erlang 中的两个函数都将传递 (Element, Accumulator)
.
我注意到 Haskell 和 Erlang 在 foldl
方面存在差异。
对于 foldr
,两种语言 return 相同的结果:
foldr (\x y -> 2*x+y) 4 [1, 2, 3] -- returns 49
lists:foldr(fun(X, Y) −> X+2∗Y end, 4, [1,2,3]). % returns 49
但是 foldl
的 return 值不同:
foldl (\x y -> x+2*y) 4 [1, 2, 3] -- returns 16
lists:foldl(fun(X, Y) −> X+2∗Y end, 4, [1,2,3]). -- returns 43
如何解释这种差异?
您没有简化折叠函数,这让您感到困惑。
左折,Haskell:
Prelude Debug.Trace> foldl (\x y -> trace("x:"++show x++" y:"++show y) $ x+y) 4 [1,2,3]
x:4 y:1
x:5 y:2
x:7 y:3
10
左折,Erlang:
1> lists:foldl(fun (X,Y) -> io:format("x:~p y:~p~n", [X,Y]), X+Y end, 4, [1,2,3]).
x:1 y:4
x:2 y:5
x:3 y:7
10
右折,Haskell:
Prelude Debug.Trace> foldr (\x y -> trace("x:"++show x++" y:"++show y) $ x+y) 4 [1,2,3]
x:3 y:4
x:2 y:7
x:1 y:9
10
右折,Erlang:
2> lists:foldr(fun (X,Y) -> io:format("x:~p y:~p~n", [X,Y]), X+Y end, 4, [1,2,3]).
x:3 y:4
x:2 y:7
x:1 y:9
10
由此可见,在Haskell中,foldl
函数将被传递(Accumulator, Element)
,而foldr
函数将被传递(Element, Accumulator)
。另一方面,Erlang 中的两个函数都将传递 (Element, Accumulator)
.