Iterator: fold
fold es el consumidor de iteradores de propósito general que reduce una secuencia a un único valor. Toma un acumulador inicial y una función de dos argumentos, aplica la función a cada elemento y al acumulador en curso, y retorna el resultado acumulado final.
Código
// fold: reducir un iterator a un valor acumulando con una función
fn add(acc: int, x: int) -> int {
return acc + x
}
fn multiply(acc: int, x: int) -> int {
return acc * x
}
fn max_val(acc: int, x: int) -> int {
if x > acc {
return x
}
return acc
}
fn is_even(x: int) -> bool {
return x % 2 == 0
}
fn main() -> int {
let nums: Array = [1, 2, 3, 4, 5]
// Suma con fold — equivale a un loop manual con acumulador
let suma: int = nums.iter().fold(0, add)
print("suma(1..5) = " + int_to_string(suma)) // 15
// Producto con fold
let producto: int = nums.iter().fold(1, multiply)
print("producto(1..5) = " + int_to_string(producto)) // 120
// Máximo con fold
let maximo: int = nums.iter().fold(0, max_val)
print("max(1..5) = " + int_to_string(maximo)) // 5
// Sumar solo los pares con filter + fold
let nums2: Array = [10, 3, 8, 7, 2, 6]
let suma_pares: int = nums2.iter().filter(is_even).fold(0, add)
print("suma pares = " + int_to_string(suma_pares)) // 26 (10+8+2+6)
// fold con valor inicial distinto de cero
let nums3: Array = [1, 2, 3]
let con_offset: int = nums3.iter().fold(100, add)
print("100 + sum(1,2,3) = " + int_to_string(con_offset)) // 106
return 0
}
Salida
suma(1..5) = 15 producto(1..5) = 120 max(1..5) = 5 suma pares = 26 100 + sum(1,2,3) = 106
Explicación
fold(init, f) es equivalente a escribir manualmente un loop con una variable acumuladora: comienza con acc = init y para cada elemento x calcula acc = f(acc, x), retornando el acc final. La elección del valor inicial es importante: 0 es el elemento neutro para la suma (sumar cero no cambia nada), mientras que 1 es el elemento neutro para la multiplicación. Elegir el valor inicial incorrecto da resultados incorrectos.
La función acumuladora max_val selecciona el mayor entre el acumulador actual y el elemento entrante, así que hacer fold sobre un array con 0 como inicio encuentra el máximo. Esto funciona correctamente aquí porque todos los valores son positivos; para arrays que puedan contener negativos, el valor inicial debería fijarse al entero mínimo posible.
Combinar filter y fold en un solo pipeline — como en el ejemplo de suma de pares — es idiomático en Nyx: filter reduce el flujo, y luego fold lo reduce a un valor, sin alocar ningún array intermedio. Muchas operaciones clásicas (sum, product, count, any, all) son casos especiales de fold y pueden expresarse de esta manera.