Patrón acumulador
Convierta a recursión de cola
Patrón acumulador es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Scala for Backend Engineering & Functional Programming, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
El patrón del acumulador
El patrón del acumulador convierte una función que no es recursiva de cola en una función recursiva de cola. Se conserva el resultado parcial en un parámetro adicional (el acumulador) en lugar de construirlo después de que la llamada devuelva el resultado.
La idea central
En lugar de n + sum(n-1) (trabajo posterior a la llamada), se calcula el nuevo total parcial antes de la llamada: sum(n-1, acc + n). Ahora la llamada recursiva es la última acción.
Antes: suma no recursiva de cola
Esta versión directa no es recursiva de cola: la suma espera a que termine la llamada recursiva.
object Main {
def sum(n: Int): Int =
if (n == 0) 0 else n + sum(n - 1)
def main(args: Array[String]): Unit = {
println(sum(50))
}
}Después: suma de cola con acumulador
Añada un parámetro acc que contenga el total acumulado. La llamada recursiva está ahora en posición de cola y puede optimizarse.
import scala.annotation.tailrec
object Main {
@tailrec
def sum(n: Int, acc: Int = 0): Int =
if (n == 0) acc else sum(n - 1, acc + n)
def main(args: Array[String]): Unit = {
println(sum(50))
}
}Factorial recursivo de cola
Aplique la misma transformación al factorial: multiplique el acumulador antes de volver a llamar a la función.
import scala.annotation.tailrec
object Main {
@tailrec
def factorial(n: Int, acc: Long = 1): Long =
if (n <= 1) acc else factorial(n - 1, acc * n)
def main(args: Array[String]): Unit = {
println(factorial(10))
}
}Ocultar el acumulador
El parámetro adicional es un detalle de implementación. Envuelva la función auxiliar recursiva de cola en una función pública clara para que quienes la llamen no vean acc.
import scala.annotation.tailrec
object Main {
def factorial(n: Int): Long = {
@tailrec
def loop(m: Int, acc: Long): Long =
if (m <= 1) acc else loop(m - 1, acc * m)
loop(n, 1)
}
def main(args: Array[String]): Unit = {
println(factorial(6))
}
}Acumular una lista
El patrón también permite construir colecciones. Una inversión recursiva de cola antepone cada cabeza al acumulador.
import scala.annotation.tailrec
object Main {
def reverse[A](xs: List[A]): List[A] = {
@tailrec
def loop(rem: List[A], acc: List[A]): List[A] = rem match {
case Nil => acc
case h :: t => loop(t, h :: acc)
}
loop(xs, Nil)
}
def main(args: Array[String]): Unit = {
println(reverse(List(1, 2, 3, 4)))
}
}Orden de acumulación
Observe que anteponer elementos al acumulador invierte el orden de forma natural. Para una función que construya una lista conservando el orden, normalmente se construye la lista invertida y se invierte al final, o se utiliza una estructura de adición eficiente.
map recursivo de cola
Construya una lista de resultados con un acumulador y, después, inviértala una sola vez al final para restaurar el orden.
import scala.annotation.tailrec
object Main {
def mapTail[A, B](xs: List[A])(f: A => B): List[B] = {
@tailrec
def loop(rem: List[A], acc: List[B]): List[B] = rem match {
case Nil => acc.reverse
case h :: t => loop(t, f(h) :: acc)
}
loop(xs, Nil)
}
def main(args: Array[String]): Unit = {
println(mapTail(List(1, 2, 3))(_ * 10))
}
}Relación con foldLeft
El patrón del acumulador es exactamente lo que generaliza foldLeft: pasa un acumulador por una colección mediante recursión de cola. Muchas funciones manuales con acumuladores pueden reescribirse como un único foldLeft.
@main def run(): Unit = {
val total = List(1, 2, 3, 4).foldLeft(0)(_ + _)
println(total)
}Cuándo utilizarlo
Recurra al patrón del acumulador cuando una función recursiva procese una estructura lineal grande y, de otro modo, pudiera desbordar la pila. A cambio de una estructura algo menos evidente, ofrece seguridad garantizada frente al desbordamiento de pila.
Comprobación rápida
Compruebe su dominio del patrón del acumulador.
Resumen
Ha aprendido el patrón del acumulador:
- Conserve el resultado parcial en un parámetro adicional.
- Calcúlelo antes de recursar para alcanzar la posición de cola.
- Oculte el acumulador detrás de una función pública clara.
- Se generaliza mediante
foldLeft.
Preguntas frecuentes
¿La lección «Patrón acumulador» es gratis?
Sí — el texto completo de «Patrón acumulador» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Scala for Backend Engineering & Functional Programming, actualiza a CoddyKit PRO. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
¿Qué aprenderé en «Patrón acumulador»?
Convierta a recursión de cola Practicas Scala for Backend Engineering & Functional Programming con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Scala for Backend Engineering & Functional Programming?
No se requiere experiencia previa. Scala for Backend Engineering & Functional Programming en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Patrón acumulador»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Scala for Backend Engineering & Functional Programming?
Sí. Cada lección de Scala for Backend Engineering & Functional Programming incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Conceptos básicos de recursión
- La anotación tailrec
- Patrón acumulador
- Trampolining