2015-12-12 13 views
8

foldlについては、HaskellとErlangの違いがあることに気付きました。 foldrについてはハスケル対erlang:foldlの違いは?

、両方の言語が同じ結果を返す:

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の戻り値は異なります

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 

はどのようにこの違いを説明することができますか?

+3

'foldl'と 'foldr'の最初の引数の引数の順番は、Haskellでは異なっているようです:' foldl :: Foldable t =>(b - > a - > b) - > b - > ta - > bとfoldr :: Foldable t =>(a→b→b)→b→ta→bとなる。 – Dogbert

+1

'2 * x + y'対' X + 2 * Y' - これは意図したものですか? – chi

+0

@chi非常に注意深く、私はこれら2つを混ぜ合わせました!しかし、問題はまだ残っていますが、まったく別の方法です。foldrは同じように動作しますが、foldlは別の番号を返します。 –

答えて

13

あなたは折り畳み機能を単純化しないであなた自身を混乱させるでしょう。左

倍、ハスケル:左

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 

倍右、ハスケル

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 

このことから、それはfoldr機能が(Element, Accumulator)を渡される一方、Haskellで、foldl機能が(Accumulator, Element)を渡されることは明らかです。一方、Erlangの両方の関数は(Element, Accumulator)に渡されます。