Este documento explica los pliegues (folds), que son funciones que reducen una lista a un solo valor. Los pliegues toman una función binaria, un valor inicial y una lista, y aplican repetidamente la función binaria al acumulador y los elementos de la lista. Se presentan ejemplos de pliegues por la izquierda y la derecha, incluyendo funciones como sumaLista, elem', map' y maximum'. También se explican variantes como foldl1, foldr1, scanl y scanr.
Este documento explica los pliegues (folds), que son funciones que reducen una lista a un solo valor. Los pliegues toman una función binaria, un valor inicial y una lista, y aplican repetidamente la función binaria al acumulador y los elementos de la lista. Se presentan ejemplos de pliegues por la izquierda y la derecha, incluyendo funciones como sumaLista, elem', map' y maximum'. También se explican variantes como foldl1, foldr1, scanl y scanr.
Este documento explica los pliegues (folds), que son funciones que reducen una lista a un solo valor. Los pliegues toman una función binaria, un valor inicial y una lista, y aplican repetidamente la función binaria al acumulador y los elementos de la lista. Se presentan ejemplos de pliegues por la izquierda y la derecha, incluyendo funciones como sumaLista, elem', map' y maximum'. También se explican variantes como foldl1, foldr1, scanl y scanr.
especie de funcin map, solo que reducen la lista a un solo valor. Estos fueron creados para encapsular listas vacas. Anteriormente debamos usar un patrnx:xsy hacamos alguna operacin con un solo elemento de la lista.
Un pliegue toma una funcin binaria, un valor inicial
y una lista que plegar. La funcin binaria es llamada con el acumulador y el primer (o ltimo) elemento y produce un nuevo acumulador. Luego, la funcin binaria se vuelve a llamar junto al nuevo acumulador y al nuevo primer (o ltimo) elemento de la lista, y as sucesivamente. sumaLista :: (Num a) => [a] -> a La funcin binaria toma dos parmetros por si misma. Cuando se ha recorrido la lista completa, solo permanece un acumulador, que es el valor al que se ha reducido la lista. La funcin binaria toma dos parmetros por si misma.
Vamos a analizar un poco este pliegue. \acc x -> acc
+ x es la funcin binaria donde suma sus parmetros. 0 es el valor inicial y xs es la lista que debe ser plegada. sumaLista1 :: (Num a) => [a] -> a sumaLista1 xs = foldl (\acc x -> acc + x) 0 xs podemos escribir esta implementacin de forma ms bonita como: sumaLista2 :: (Num a) => [a] -> a sumaLista2 = foldl (+) 0 Tambin simplificando
sumaLista3 :: (Num a) => [a] -> a
sumaLista3 = foldl1 (+)
ghci> sum' [3,5,2,1]
11
Vamos a implementar otra funcin con un pliegue
por la izquierda antes de continuar con los pliegues por la derecha.
elem' :: (Eq a) => a -> [a] -> Bool
elem' y ys = foldl (\acc x -> if x == y then True else acc) False ys *Main> elem' 5 [5..50] True *Main> elem' 5 [8..50] False
Ahora los pliegues por la derecha funcionan igual
que los pliegues por la izquierda, solo que el acumulador consume elemento por la derecha. La funcin binaria de los pliegues por la izquierda como primer parmetro el acumulador y el valor actual como segundo parmetro. \acc x > ...
La funcin binaria de los pliegues por la derecha
tiene el valor actual como primer parmetro y el acumulador despus. \x acc > ...
Vamos a implementar la funcin map con un
pliegue por la derecha. El acumulador ser una lista, en la que iremos acumulando los elemento de la lista ya mapeados. Es obvio que el valor inicial ser una lista vaca. map' :: (a -> b) -> [a] -> [b] map' f xs = foldr (\x acc -> f x : acc) [] xs
pliegue por la derecha como si fuera un pliegue por la izquierda y viceversa.
Una gran diferencia es que los pliegues por la
derecha funcionan con listas infinitas, mientras que los pliegues por la izquierda no.
Los pliegues se pueden utilizar para implementar
cualquier funcin que recorra una lista, elemento a elemento, y luego devuelvan un valor. Siempre que quieras recorrer una lista y devolver un valor, hay posibilidades de utilizar un pliegue. Las funciones foldl1 y foldr1 son muy parecidas a foldl y foldr, solo que no necesitas indicar un valor de inicio. maximum' :: (Ord a) => [a] -> a maximum' = foldr1 (\x acc -> if x > acc then x else acc)
scanl y scanr son como foldl y foldr, solo que
devuelven todos los acumuladores intermedios en forma de lista. Existen tambin scanl1 y scanr1, que son similares a foldl1 y foldr1. ghci> scanl (+) 0 [3,5,2,1] [0,3,8,10,11] ghci> scanr (+) 0 [3,5,2,1] [11,8,3,1,0]
Cuando usamos scanl, el resultado final ser el
ltimo elemento de la lista resultante mientras que con scanr estar al principio.