Esta es una respuesta complementaria para ayudar a explicar mapas y pliegues. Para los ejemplos a continuación, usaré esta lista. Recuerde, esta lista es inmutable, por lo que nunca cambiará:
var numbers = [1, 2, 3, 4, 5]
Usaré números en mis ejemplos porque conducen a un código fácil de leer. Sin embargo, recuerde que los pliegues se pueden usar para cualquier cosa para la que se pueda usar un ciclo imperativo tradicional.
Un mapa toma una lista de algo y una función, y devuelve una lista que fue modificada usando la función. Cada elemento se pasa a la función y se convierte en lo que devuelve la función.
El ejemplo más fácil de esto es simplemente agregar un número a cada número en una lista. Usaré pseudocódigo para que sea independiente del lenguaje:
function add-two(n):
return n + 2
var numbers2 =
map(add-two, numbers)
Si imprimiste numbers2
, verías [3, 4, 5, 6, 7]
cuál es la primera lista con 2 agregados a cada elemento. Observe que la función add-two
se le dio map
a usar.
Los pliegues son similares, excepto que la función que debe darles debe tomar 2 argumentos. El primer argumento suele ser el acumulador (en un pliegue izquierdo, que son los más comunes). El acumulador son los datos que se pasan durante el bucle. El segundo argumento es el elemento actual de la lista; al igual que arriba para la map
función.
function add-together(n1, n2):
return n1 + n2
var sum =
fold(add-together, 0, numbers)
Si imprimiera sum
, vería la suma de la lista de números: 15.
Aquí están los argumentos a fold
hacer:
Esta es la función que le estamos dando al doblez. El pliegue pasará la función al acumulador actual y al elemento actual de la lista. Lo que devuelva la función se convertirá en el nuevo acumulador, que pasará a la función la próxima vez. Así es como "recuerda" los valores cuando se repite al estilo FP. Le di una función que toma 2 números y los agrega.
Este es el acumulador inicial; cómo comienza el acumulador antes de que se procesen los elementos de la lista Cuando sumas números, ¿cuál es el total antes de que hayas sumado números? 0, que pasé como segundo argumento.
Por último, al igual que con el mapa, también pasamos la lista de números para que se procese.
Si los pliegues aún no tienen sentido, considere esto. Cuando escribes:
# Notice I passed the plus operator directly this time,
# instead of wrapping it in another function.
fold(+, 0, numbers)
Básicamente, coloca la función aprobada entre cada elemento de la lista y agrega el acumulador inicial a la izquierda o a la derecha (dependiendo de si es un pliegue a la izquierda o a la derecha), entonces:
[1, 2, 3, 4, 5]
Se convierte en:
0 + 1 + 2 + 3 + 4 + 5
^ Note the initial accumulator being added onto the left (for a left fold).
Lo que equivale a 15.
Use a map
cuando desee convertir una lista en otra lista, de la misma longitud.
Use a fold
cuando desee convertir una lista en un solo valor, como sumar una lista de números.
Sin embargo, como señaló @Jorg en los comentarios, el "valor único" no necesita ser algo simple como un número; ¡podría ser cualquier objeto individual, incluida una lista o una tupla! La forma en que realmente hice pliegues para mí fue definir un mapa en términos de pliegue. Observe cómo el acumulador es una lista:
function map(f, list):
fold(
function(xs, x): # xs is the list that has been processed so far
xs.add( f(x) ) # Add returns the list instead of mutating it
, [] # Before any of the list has been processed, we have an empty list
, list)
Honestamente, una vez que comprenda cada uno, se dará cuenta de que casi cualquier bucle puede ser reemplazado por un pliegue o un mapa.