Fold resuelve las limitaciones del reduce
- Permite setear el acumulador, por lo tanto podemos trabajar con listas vacias
- Permite trabajar transformaciones de tipos, por ejemplo sumar los tamaños de una lista de string
El foldLeft y foldRight retornar un reduce con el acc seteado
scala> List("Hola","Mundo","Cruel") reduceLeft ((acc,x) => acc + x.length) val res5: String = Hola55 scala> List("Hola","Mundo","Cruel") reduceRight ((acc,x) => acc + x.length) val res6: String = Hola6 scala> (List("Hola","Mundo","Cruel") foldLeft 0) _ val res7: ((Int, String) => Int) => Int = $Lambda$2624/0x00007f5f0c645218@193792e6
scala> (List("Hola","Mundo","Cruel") foldLeft 0) ( (acc,x) => x.length+acc)
val res11: Int = 14
Implementación¶
import scala.annotation.tailrec
object Reducir {
//FoldLeft
def foldir[U,V](l:List[U])(acc:V)(f: (V,U) => V):V = {
@tailrec
def foldirI(l:List[U])(acc:V):V = {
l match {
case Nil => acc // Lista vacía, retorna acumulador
case x :: xs => foldirI(xs)(f(acc,x)) // Aplica función y recursión tail
}
}
foldirI(l)(acc) // Inicia recursión con acumulador proporcionado
}
// FoldRight
def foldeR[U,V](l:List[U])(acc:V)(f : (U,V)=>V):V = {
l match {
case Nil => acc // Caso base: lista vacía
case x :: xs => f(x, foldeR(xs)(acc)(f)) // Recursión hacia atrás
}
}
def main(args: Array[String]): Unit = {
// Pruebas con foldir (foldLeft personalizado)
println(foldir[Int,Int](List(1,2,3))(0)((acc,x) => acc+x)) // Suma: 0+1+2+3 = 6
println(foldir[Int,Int](List(1,2,3,4))(0)((acc,x) => acc*x)) // Multiplicación: 0*1*2*3*4 = 0
// Comparación resta con foldLeft (mismo orden)
println(foldir[Int,Int](List(1,2,3,4))(0)((acc,x) => acc-x)) // ((0-1)-2)-3)-4 = -10
println((List(1,2,3,4) foldLeft 0)((acc,x) => acc-x)) // Mismo resultado: -10
// Comparación resta con foldRight (orden diferente)
println(foldeR[Int,Int](List(1,2,3,4))(0)((acc,x) => acc-x)) // 1-(2-(3-(4-0))) = -2
println((List(1,2,3,4) foldRight 0) ((acc,x) => acc-x)) // Mismo resultado: -2
// Ejemplos con tipos diferentes (String -> Int)
println((List("Hola","Mundo","Cruel") foldLeft 0) ( (acc,x) => x.length+acc)) // Suma longitudes: 4+5+5 = 14
println(foldir[String,Int](List("Hola","Mundo","Cruel"))(0)( (acc,x) => x.length+acc)) // Mismo resultado: 14
}
}