Вспомните определение foldl
:
foldl f acc [] = acc
foldl f acc (x:xs) = foldl f (f acc x) xs
Теперь, лучший способ понять сгибы - это пройти оценку.Итак, начнем с:
sum [3,5,2,1]
== foldl (\acc x -> acc + x) 0 [3,5,2,1]
Вторая строка определения функции foldl
означает, что это эквивалентно следующему:
== foldl (\acc x -> acc + x) ((\acc x -> acc + x) 0 3) [5,2,1]
Теперь, когда применяется лямбда-выражениек параметрам 0
и 3
передаются как acc
и x
:
== 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]
== 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
:
== ((((0+3)+5)+2)+1)
Итак, чтобы ответить на ваш вопрос напрямую: функция знает значения acc
и x
просто потому, что определение foldl
передает свои значения в функцию в качестве параметров.