#!/usr/bin/env catnip
# fold et reduce
print("⇒ fold : agrégation avec valeur initiale")
# Somme
total = fold(list(1, 2, 3, 4, 5), 0, (acc, x) => { acc + x })
print("Somme 1..5:", total)
# Produit
produit = fold(list(1, 2, 3, 4), 1, (acc, x) => { acc * x })
print("Produit 1..4:", produit)
# Concaténation
mot = fold(list("c", "a", "t"), "", (acc, x) => { acc + x })
print("Concat:", mot)
print()
print("⇒ fold sur collection vide")
# fold est total : sur une liste vide, retourne init
vide = fold(list(), 0, (acc, x) => { acc + x })
print("fold(list(), 0, +):", vide)
print()
print("⇒ fold un seul niveau")
# fold n'effectue pas de descente récursive
taille_totale = fold(
list(list(1, 2), list(3, 4)),
0,
(acc, row) => {
acc + len(row)
}
)
print("Éléments dans sous-listes:", taille_totale)
print()
print("⇒ reduce : sans valeur initiale")
# Le premier élément sert d'accumulateur
somme = reduce(list(10, 20, 30), (acc, x) => { acc + x })
print("reduce sum:", somme)
# Maximum artisanal
maximum = reduce(
list(3, 1, 4, 1, 5, 9, 2, 6),
(acc, x) => {
if x > acc { x } else { acc }
}
)
print("Maximum:", maximum)
print()
print("⇒ Composition broadcast + fold")
# broadcast transforme, fold agrège
resultat = fold(list(1, 2, 3).[* 10], 0, (acc, x) => { acc + x })
print("list(1,2,3).[*10] puis fold +:", resultat)
# Pipeline complet : transformer puis agréger
cubes = fold(list(1, 2, 3, 4).[** 3], 0, (acc, x) => { acc + x })
print("Somme des cubes 1..4:", cubes)
print()
print("⇒ reduce par monoïdes nommés")
data = list(3, -1, 4, -1, 5, 9, -2, 6)
# Un monoïde : la valeur agrégée
print("sum:", reduce(data, sum))
print("len:", reduce(data, len))
print("max:", reduce(data, max))
# Plusieurs monoïdes : un tuple, en une passe
print("sum, len, max:", reduce(data, sum, len, max))
# concat aplatit un niveau ; any/all réduisent des booléens
print("concat:", reduce(list(list(1, 2), list(3), list(4, 5)), concat))
print("all:", reduce(list(True, True, False), all))
# Un callback lambda reste sur le reduce classique
print("callback:", reduce(list(1, 2, 3, 4), (a, b) => { a + b }))