Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

haskell foldl with (++)

Tags:

haskell

ghc

I was playing with Haskell and ghci when I found this which really bothers me:

foldl (++) [[3,4,5], [2,3,4], [2,1,1]] []

I expected to get this: [3,4,5,2,3,4,2,1,1] However it gets:

[[3,4,5],[2,3,4],[2,1,1]]

As far as I understand foldl, it should be this:

(([] ++ [3, 4, 5]) ++ [2, 3, 4]) ++ [2, 1, 1]

If I type this in ghci it really is [3,4,5,2,3,4,2,1,1].

And the other strange thing is this:

Prelude> foldl1 (++) [[3,4,5], [2, 3, 4], [2, 1, 1]]
[3,4,5,2,3,4,2,1,1]

I expect foldl and foldl1 to behave in the same way. So what does foldl actually do?

like image 308
Mariy Avatar asked Feb 26 '11 18:02

Mariy


People also ask

What does Foldl do in Haskell?

Haskell : foldl. Description: it takes the second argument and the first item of the list and applies the function to them, then feeds the function with this result and the second argument and so on. See scanl for intermediate results.

What is the difference between Foldl and Foldl?

Only foldr is lazy and can be used for codata/infinite streams. While foldl is tail-recursive (enhanced with strict application foldl' can avoid stack overflow). This is why foldr should be used by default in Haskellin order preserve laziness across function composition.

What is fold in functional programming?

In functional programming, fold (also termed reduce, accumulate, aggregate, compress, or inject) refers to a family of higher-order functions that analyze a recursive data structure and through use of a given combining operation, recombine the results of recursively processing its constituent parts, building up a ...


2 Answers

The order of arguments is wrong. The right one is: foldl (++) [] [[3,4,5], [2,3,4], [2,1,1]] (That is, first the accumulator, then the list.)

like image 89
adamax Avatar answered Sep 29 '22 16:09

adamax


You switched the arguments around. foldl takes the accumulator's starting value first, then the list to fold. So what happens in your case is that foldl folds over the empty list and thus returns the starting value, which is [[3,4,5], [2, 3, 4], [2, 1, 1]]. This will do what you want:

foldl (++) [] [[3,4,5], [2, 3, 4], [2, 1, 1]]
like image 24
sepp2k Avatar answered Sep 29 '22 16:09

sepp2k