Accumulatorpatroon
Omzetten naar tailrecursie
Accumulatorpatroon is een gratis Scala voor backend-engineering en functioneel programmeren-les op CoddyKit. Dit is les 3 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Scala voor backend-engineering en functioneel programmeren. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Scala voor backend-engineering en functioneel programmeren bevat in totaal 4 lessen.
Het accumulatorpatroon
Met het accumulatorpatroon verander je een niet-staartrecursieve functie in een staartrecursieve functie. Je geeft het gedeeltelijke resultaat mee in een extra parameter (de accumulator) in plaats van het na terugkeer van de aanroep op te bouwen.
Het kernidee
In plaats van n + sum(n-1) (werk na de aanroep), bereken je het nieuwe gedeeltelijke totaal vóór de aanroep: sum(n-1, acc + n). Nu is de recursieve aanroep de laatste actie.
Voorheen: niet-staartrecursieve som
Deze directe versie is niet staartrecursief: de optelling wacht op de recursieve aanroep.
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))
}
}Daarna: staartsom met accumulator
Voeg een parameter acc toe die het lopende totaal bevat. De recursieve aanroep staat nu in de staartpositie en kan worden geoptimaliseerd.
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))
}
}Staartrecursieve faculteit
Pas dezelfde transformatie toe op de faculteit: vermenigvuldig vóór de recursie met de accumulator.
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))
}
}De accumulator verbergen
De extra parameter is een implementatiedetail. Wikkel de staartrecursieve hulpfunctie in een nette publieke functie, zodat aanroepers acc niet zien.
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))
}
}Een lijst accumuleren
Het patroon kan ook verzamelingen opbouwen. Een staartrecursieve omkering voegt elke kop vooraan toe aan de accumulatorlijst.
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)))
}
}Volgorde van accumulatie
Let op: vooraan toevoegen aan de accumulator keert de volgorde vanzelf om. Bij een functie die een lijst opbouwt en de volgorde behoudt, bouw je vaak eerst een omgekeerde lijst en draai je die aan het einde om, of gebruik je een efficiënte structuur voor toevoegen achteraan.
Staartrecursieve map
Bouw een resultaatlijst met een accumulator en draai die aan het einde één keer om om de volgorde te herstellen.
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))
}
}Relatie met foldLeft
Het accumulatorpatroon is precies wat foldLeft generaliseert: het geeft een accumulator staartrecursief door een verzameling heen. Veel handmatige accumulatorfuncties kun je herschrijven als één foldLeft.
@main def run(): Unit = {
val total = List(1, 2, 3, 4).foldLeft(0)(_ + _)
println(total)
}Wanneer gebruik je dit
Gebruik het accumulatorpatroon wanneer een recursieve functie een grote lineaire structuur verwerkt en anders de stack zou laten overlopen. Je ruilt een iets minder voor de hand liggende vorm in voor gegarandeerde stackveiligheid.
Korte toets
Toets je begrip van het accumulatorpatroon.
Samenvatting
Je hebt het accumulatorpatroon geleerd:
- Geef het gedeeltelijke resultaat mee in een extra parameter.
- Bereken het vóór de recursieve aanroep om de staartpositie te bereiken.
- Verberg de accumulator achter een nette publieke functie.
- Het patroon wordt gegeneraliseerd door
foldLeft.
Leer Scala met een AI-tutor — gratis
Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.
- Cursussen
- 39
- Lessen
- 143
Veelgestelde vragen
Is de les “Accumulatorpatroon” gratis?
Ja — de volledige tekst van “Accumulatorpatroon” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Scala voor backend-engineering en functioneel programmeren wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Scala voor backend-engineering en functioneel programmeren bevat in totaal 4 lessen.
Wat leer ik in “Accumulatorpatroon”?
Omzetten naar tailrecursie Je oefent met Scala voor backend-engineering en functioneel programmeren door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.
Heb ik ervaring nodig om met Scala voor backend-engineering en functioneel programmeren te beginnen?
Ervaring vooraf is niet nodig. Scala voor backend-engineering en functioneel programmeren op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.
Hoe lang duurt de les “Accumulatorpatroon”?
De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.
Kan ik code schrijven en uitvoeren in deze les over Scala voor backend-engineering en functioneel programmeren?
Ja. Elke les over Scala voor backend-engineering en functioneel programmeren bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.
Alle lessen in deze cursus
- De basis van recursie
- De annotatie tailrec
- Accumulatorpatroon
- Trampolining