Nyx con Ejemplos

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.

← Anterior Siguiente →

Source: examples/by-example/30-iterator-fold.nx