Mariy
Mariy

Reputation: 5914

haskell foldl with (++)

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?

Upvotes: 7

Views: 829

Answers (3)

Logan Capaldo
Logan Capaldo

Reputation: 40336

You got the argument order wrong

Prelude> :t foldl
foldl :: (a -> b -> a) -> a -> [b] -> a
Prelude> :t foldl1
foldl1 :: (a -> a -> a) -> [a] -> a

The initial value comes first. In your case, your initial value was [[3,4,5],[2,3,4],[2,1,1]] and you folded over the empty list, so you got back the initial value.

Upvotes: 2

sepp2k
sepp2k

Reputation: 370172

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]]

Upvotes: 5

adamax
adamax

Reputation: 3865

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.)

Upvotes: 21

Related Questions