0Pricing
Scala for Backend Engineering & Functional Programming · Aula

Padrão acumulador

Converta para recursão de cauda.

Padrão acumulador é uma aula grátis de Scala for Backend Engineering & Functional Programming no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Scala for Backend Engineering & Functional Programming, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.

Partes desta aula ainda não foram traduzidas e aparecem em inglês.

The Accumulator Pattern

The accumulator pattern converts a non-tail-recursive function into a tail-recursive one. You carry the partial result in an extra parameter (the accumulator) instead of building it up after the call returns.

The Core Idea

Instead of n + sum(n-1) (work after the call), you compute the new partial total before the call: sum(n-1, acc + n). Now the recursive call is the last action.

Before: Non-Tail Sum

This direct version is not tail-recursive: the addition waits for the recursive call.

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))
  }
}

After: Tail Sum with Accumulator

Add an acc parameter that holds the running total. The recursive call is now in tail position and can be optimized.

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))
  }
}

Tail-Recursive Factorial

Apply the same transformation to factorial: multiply into the accumulator before recursing.

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))
  }
}

Hiding the Accumulator

The extra parameter is an implementation detail. Wrap the tail-recursive worker in a clean public function so callers do not see 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))
  }
}

Accumulating a List

The pattern also builds collections. A tail-recursive reverse prepends each head to the accumulator list.

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)))
  }
}

Order of Accumulation

Note that prepending to the accumulator naturally reverses order. For a list-building function that preserves order, you often build reversed and reverse at the end, or use an efficient append structure.

Tail-Recursive map

Build a result list with an accumulator, then reverse once at the end to restore order.

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))
  }
}

Relation to foldLeft

The accumulator pattern is exactly what foldLeft generalizes: it threads an accumulator through a collection tail-recursively. Many manual accumulator functions can be rewritten as a single foldLeft.

@main def run(): Unit = {
  val total = List(1, 2, 3, 4).foldLeft(0)(_ + _)
  println(total)
}

When to Use It

Reach for the accumulator pattern when a recursive function processes a large linear structure and would otherwise overflow the stack. It trades a slightly less obvious shape for guaranteed stack safety.

Quick Check

Test your grasp of the accumulator pattern.

Recap

You learned the accumulator pattern:

  • Carry the partial result in an extra parameter.
  • Compute it before recursing to reach tail position.
  • Hide the accumulator behind a clean public function.
  • It generalizes to foldLeft.

Perguntas Frequentes

A aula “Padrão acumulador” é grátis?

Sim — o texto completo de “Padrão acumulador” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Scala for Backend Engineering & Functional Programming, atualize para CoddyKit PRO. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.

O que vou aprender em “Padrão acumulador”?

Converta para recursão de cauda. Você pratica Scala for Backend Engineering & Functional Programming com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Scala for Backend Engineering & Functional Programming?

Nenhuma experiência prévia é necessária. Scala for Backend Engineering & Functional Programming no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Padrão acumulador”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Scala for Backend Engineering & Functional Programming?

Sim. Cada aula de Scala for Backend Engineering & Functional Programming inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Fundamentos da recursão
  2. A anotação tailrec
  3. Padrão acumulador
  4. Trampolim
← Voltar para Scala for Backend Engineering & Functional Programming