foldLeft e foldRight
Reduza coleções a um valor.
foldLeft e foldRight é 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.
Dobrando uma coleção
A dobra reduz uma coleção a um único valor, combinando repetidamente os elementos com um acumulador.
O padrão de acumulador que você aprendeu é exatamente o que fold abstrai. Em vez de escrever a função auxiliar recursiva, você fornece um valor inicial e uma função de combinação.
Fundamentos de foldLeft
foldLeft recebe um acumulador inicial e uma função (acc, element) e percorre a coleção da esquerda para a direita.
A cada etapa, ele substitui o acumulador pelo resultado da função.
val xs = List(1, 2, 3, 4)
val total = xs.foldLeft(0)((acc, x) => acc + x)
@main def run(): Unit =
println(total) // 10Como foldLeft associa
foldLeft agrupa a partir da esquerda. Para List(1, 2, 3) com a semente z, ele calcula f(f(f(z, 1), 2), 3).
O acumulador é o argumento esquerdo, portanto acumula à medida que você avança para a direita pela lista.
// List(1, 2, 3).foldLeft(0)(_ + _)
// = ((0 + 1) + 2) + 3
// = 6Fundamentos de foldRight
foldRight também combina elementos, mas começa pela direita.
Sua função recebe (element, acc), com o elemento à esquerda e o acumulador à direita.
val xs = List(1, 2, 3, 4)
val total = xs.foldRight(0)((x, acc) => x + acc)
@main def run(): Unit =
println(total) // 10Como foldRight associa
foldRight agrupa a partir da direita. Para List(1, 2, 3) com a semente z, ele calcula f(1, f(2, f(3, z))).
A semente fica na extremidade direita, e a lista é combinada para dentro a partir do final.
// List(1, 2, 3).foldRight(0)(_ + _)
// = 1 + (2 + (3 + 0))
// = 6Quando a direção importa
Para operações associativas e comutativas, como soma ou produto, as duas dobras produzem a mesma resposta.
Para operações não comutativas, como subtração ou construção de listas, a direção altera o resultado. Escolha conscientemente.
val xs = List(1, 2, 3)
val l = xs.foldLeft(0)(_ - _) // ((0-1)-2)-3 = -6
val r = xs.foldRight(0)(_ - _) // 1-(2-(3-0)) = 2
@main def run(): Unit =
println((l, r)) // (-6, 2)Construindo uma lista
foldRight é a escolha natural para reconstruir uma lista na ordem, porque trabalha da cauda para dentro e adicionar elementos no início os mantém no lugar.
Isso transforma cada elemento preservando a ordem.
val xs = List(1, 2, 3)
val doubled = xs.foldRight(List.empty[Int]) { (x, acc) =>
(x * 2) :: acc
}
@main def run(): Unit =
println(doubled) // List(2, 4, 6)foldLeft inverte
Se você construir uma lista com foldLeft e adicionar elementos no início, o resultado ficará invertido, porque os elementos são adicionados primeiro à frente à medida que você avança para a direita.
Às vezes, isso é exatamente o que você deseja.
val xs = List(1, 2, 3)
val rev = xs.foldLeft(List.empty[Int]) { (acc, x) =>
x :: acc
}
@main def run(): Unit =
println(rev) // List(3, 2, 1)Segurança da pilha
foldLeft é recursivo de cauda e executado como um laço, portanto é seguro em coleções enormes.
foldRight em uma List não é recursivo de cauda e pode causar estouro da pilha em listas muito longas. Prefira foldLeft quando não precisar da ordem da direita para a esquerda.
// Safe even for millions of elements:
val n = (1 to 1000000).foldLeft(0L)(_ + _)
// foldRight on a long List risks StackOverflowErrorAlterando o tipo do resultado
O tipo do acumulador pode ser diferente do tipo dos elementos.
Aqui, dobramos uma lista de inteiros em uma string, portanto a semente é uma string vazia e cada etapa adiciona conteúdo ao final.
O tipo da dobra é determinado pela semente.
val xs = List(1, 2, 3)
val s = xs.foldLeft("")((acc, x) => acc + x.toString)
@main def run(): Unit =
println(s) // "123"A dobra como ferramenta versátil
Muitas operações de lista são casos especiais de fold: sum, produto, tamanho, max, map, filtragem, reverse.
Reconhecer a operação de fold subjacente ajuda você a escrever código conciso e declarativo em vez de recursão criada manualmente.
val xs = List(4, 1, 7, 3)
val maxV = xs.foldLeft(Int.MinValue)(_ max _)
val len = xs.foldLeft(0)((acc, _) => acc + 1)
@main def run(): Unit =
println((maxV, len)) // (7, 4)Verificação rápida
Raciocine sobre a direção da dobra e a posição da semente.
Recapitulação
foldLeft percorre da esquerda para a direita, com o acumulador à esquerda, e calcula ((z op a) op b) op c. Ele é recursivo de cauda e seguro para a pilha.
foldRight percorre da direita para a esquerda, com a semente à direita, e calcula a op (b op (c op z)). É adequado para construir listas preservando a ordem, mas pode causar estouro em listas longas.
A semente determina o tipo do resultado, portanto as dobras podem transformar uma coleção em qualquer valor.
Perguntas Frequentes
A aula “foldLeft e foldRight” é grátis?
Sim — o texto completo de “foldLeft e foldRight” é 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 “foldLeft e foldRight”?
Reduza coleções a um valor. 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 “foldLeft e foldRight”?
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
- Pensando recursivamente
- Padrões de acumuladores
- foldLeft e foldRight
- reduce e agregação