Recall the definition of foldl:
foldl f acc [] = acc
foldl f acc (x:xs) = foldl f (f acc x) xs
Now, the best way to understand folds is to walk through the evaluation. So let's start with:
sum [3,5,2,1]
== foldl (\acc x -> acc + x) 0 [3,5,2,1]
The second line of the definition of the foldl function means this is equivalent to the following:
== foldl (\acc x -> acc + x) ((\acc x -> acc + x) 0 3) [5,2,1]
Now since the lambda expression is applied to parameters, 0 and 3 are passed in as acc and x:
== foldl (\acc x -> acc + x) (0+3) [5,2,1]
And the process repeats:
== foldl (\acc x -> acc + x) ((\acc x -> acc + x) (0+3) 5) [2,1]
== foldl (\acc x -> acc + x) ((0+3)+5) [2,1]
== foldl (\acc x -> acc + x) ((\acc x -> acc + x) ((0+3)+5) 2) [1]
== foldl (\acc x -> acc + x) (((0+3)+5)+2) [1]
== foldl (\acc x -> acc + x) ((\acc x -> acc + x) (((0+3)+5)+2) 1) []
== foldl (\acc x -> acc + x) ((((0+3)+5)+2)+1) []
At this point, evaluation continues according to the first line of the foldl definition:
== ((((0+3)+5)+2)+1)
So to answer your question directly: the function knows the values of acc and x simply because the definition of foldl passes their values to the function as parameters.
foldlfunction is equivalent to a for loop. For example,foldl (\acc x -> acc + x) 0 xsis equivalent toacc = 0; for (x of xs) { acc = acc + x; } return acc;. - Aadit M Shah