2015-12-12 14 views
8

Ich habe bemerkt, dass es einen Unterschied zwischen Haskell und Erlang gibt, wenn es um foldl geht.Haskell vs. Erlang: Unterschied in Foldl?

Für foldr, kehren beide Sprachen die gleichen Ergebnisse:

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 

Aber die Rückgabewerte für foldl sind unterschiedlich:

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 

Wie kann dieser Unterschied zu erklären?

+3

Die Reihenfolge der Argumente zum ersten Argument von 'foldl' und' foldr' scheint in Haskell anders zu sein: 'faltl :: Faltbares t => (b -> a -> b) -> b -> ta - > b' und 'foldr :: Faltbares t => (a -> b -> b) -> b -> ta -> b'. – Dogbert

+1

'2 * x + y' vs' X + 2 * Y' - ist das beabsichtigt? – chi

+0

@chi Sehr aufmerksam, es stellt sich heraus, ich habe diese beiden gemischt! Das Problem besteht jedoch immer noch, außer dass es jetzt genau umgekehrt ist. 'Foldr' verhält sich genauso, aber' foldl' gibt eine andere Zahl zurück. –

Antwort

13

Sie verwirren sich, indem Sie Ihre Falzfunktion nicht vereinfachen.

fach links, 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 

fach links, 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 

fach rechts, 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 

fach rechts, 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 

Aus diesem Grunde ist es klar, dass in Haskell, die foldl Funktion (Accumulator, Element) weitergegeben werden, während die foldr Funktion (Element, Accumulator) übergeben werden. Auf der anderen Seite werden beide Funktionen in Erlang (Element, Accumulator) übergeben.