Foldr y Foldl

foldr y foldl son funciones de plegado sobre la estructura recursiva de las listas.

Cumpliendose que:

foldr f z (x1 : (x2 : (… : (xn : []))))
= x1 ‘f’ (x2 ‘f’ (… ‘f’ (xn ‘f’ z))))

foldl f z (x1 : (x2 : (… : (xn : []))))
= ((((z ‘f’ x1) ‘f’ x2) … ‘f’ xn-1) ‘f’ xn)

En ambas se toma una función y se la aplica sucesivamente a cada miembre de una lista, hasta recibir un resultado final.

Ejemplos. Definición de una función and que devuelve True si todos los elementos de una lista de Bool son verdaderos y definición de una función or que devuelve True si alguno es verdadero.


and3 :: [Bool] -> Bool
and3 = foldr (&&) True

or3 :: [Bool] -> Bool
or3 = foldr (||) False

scanl y scanl, devuelven los pasos intermedios de una operación de foldl y foldr respectivamente. Los siguientes ejemplos demuestran que si una operación no es asociativa (como la resta en los naturales) foldr y foldl devuelven resultados distintos.


*Main> scanl (+) 0 [1..5]
[0,1,3,6,10,15]
*Main> scanr (+) 0 [1..5]
[15,14,12,9,5,0]

*Main> scanr (-) 0 [1..5]
[3,-2,4,-1,5,0]
*Main> scanl (-) 0 [1..5]
[0,-1,-3,-6,-10,-15]

El segundo argumento es el caso final o primero a aplicarse.


*Main> scanl (*) 10 [1..5]
[10,10,20,60,240,1200]
*Main> scanr (*) 10 [1..5]
[1200,1200,600,200,50,10]

Referencias

Razonando con Haskell;Blas C. Ruiz, Francisco Gutiérrez, Pablo Guerrero y José E. Gallardo;Thomson Editores Spain;2004