0Pricing
Scala for Backend Engineering & Functional Programming · Ders

Birikim Kalıpları

Durumu özyineleme boyunca taşıyın.

Birikim Kalıpları, CoddyKit'te ücretsiz bir Scala for Backend Engineering & Functional Programming dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Scala for Backend Engineering & Functional Programming öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Scala for Backend Engineering & Functional Programming kursu toplamda 4 dersten oluşur.

Birikim Değişkenleri Neden Kullanılır

Basit özyineleme, sonucunu özyinelemeli çağrı döndükten sonra çağrı yığını boyunca geri çıkarken oluşturur.

Birikim değişkeni ise devam eden sonucu her çağrıya aşağı doğru taşır; böylece temel duruma ulaşıldığında yanıt hazır olur.

Bu küçük değişiklik kuyruk özyinelemesini ve sabit yığın kullanımını mümkün kılar.

Yardımcı İşlev

Birikim yaklaşımı, fazladan bir parametre (şu ana kadarki sonuç) alan iç içe bir yardımcı işlev kullanır.

Dış işlev, yardımcı işlevi genellikle 0 veya boş bir liste olan başlangıç değeriyle başlatır.

def sum(xs: List[Int]): Int = {
  def loop(rest: List[Int], acc: Int): Int = rest match {
    case Nil    => acc
    case h :: t => loop(t, acc + h)
  }
  loop(xs, 0)
}

Birikim Değişkenini Çalıştırma

Buradaki eksiksiz program, bir listeyi birikim değişkeni kullanarak toplar.

Temel durumun 0 yerine doğrudan acc döndürdüğüne dikkat edin. Liste boyunca aşağı inerken toplam oluşturulmuştur.

def sum(xs: List[Int]): Int = {
  def loop(rest: List[Int], acc: Int): Int = rest match {
    case Nil    => acc
    case h :: t => loop(t, acc + h)
  }
  loop(xs, 0)
}

@main def run(): Unit =
  println(sum(List(1, 2, 3, 4)))  // 10

İki Yapının Karşılaştırılması

Basit özyinelemede birleştirme adımı (h + ...) iç çağrıyı bekler.

Birikim değişkeni kullanılan sürümde birleştirme çağrıdan önce gerçekleşir ve çağrı, işlevin yaptığı son şeydir.

Onu kuyruk özyinelemeli yapan özellik, bu son çağrı niteliğidir.

// Plain: combine after the call
case h :: t => h + sum(t)

// Accumulator: combine before the call
case h :: t => loop(t, acc + h)

Kuyruk Özyinelemesi

Kuyruk özyinelemeli çağrı, özyinelemeli çağrının işlevin son eylemi olduğu ve sonrasında yapılacak hiçbir şey kalmadığı çağrıdır.

Scala bunu tek bir yığın çerçevesini yeniden kullanarak döngüye dönüştürecek şekilde iyileştirebilir; böylece özyineleme ne kadar derin olursa olsun yığın taşmaz.

import scala.annotation.tailrec

@tailrec
def countDown(n: Int): Unit =
  if (n < 0) ()
  else { println(n); countDown(n - 1) }

@tailrec Açıklaması

@tailrec eklemek, derleyiciden işlevin gerçekten kuyruk özyinelemeli olduğunu doğrulamasını ister.

Öyle değilse derleme açık bir hatayla başarısız olur. Böylece sessiz bir performans tuzağı, derleme zamanında güvenceye dönüşür.

import scala.annotation.tailrec

def sum(xs: List[Int]): Int = {
  @tailrec
  def loop(rest: List[Int], acc: Int): Int = rest match {
    case Nil    => acc
    case h :: t => loop(t, acc + h)
  }
  loop(xs, 0)
}

@main def run(): Unit = println(sum((1 to 100000).toList))

Liste Biriktirme

Birikim değişkenlerinin sayıları tutması gerekmez. Koleksiyonlar da oluşturabilirler.

Bu reverse işlevi her başı birikim değişkeninin başına ekler ve sıralamayı doğal olarak tersine çevirir. :: ile başa ekleme hızlı olduğundan bu yöntem verimlidir.

def reverse[A](xs: List[A]): List[A] = {
  def loop(rest: List[A], acc: List[A]): List[A] = rest match {
    case Nil    => acc
    case h :: t => loop(t, h :: acc)
  }
  loop(xs, Nil)
}

reverse Uygulamada

Birikim değişkeni boş başlar ve girdiyi tükettikçe büyür.

Her baş acc'nin önüne eklendiği için ilk öğe sona gelir ve sabit yığın maliyetiyle ters çevrilmiş bir liste elde edilir.

def reverse[A](xs: List[A]): List[A] = {
  def loop(rest: List[A], acc: List[A]): List[A] = rest match {
    case Nil    => acc
    case h :: t => loop(t, h :: acc)
  }
  loop(xs, Nil)
}

@main def run(): Unit =
  println(reverse(List(1, 2, 3)))  // List(3, 2, 1)

Birden Çok Birikim Değişkeni

Bir yardımcı işlev aynı anda birkaç birikim değişkeni taşıyabilir.

Burada aynı döngüde devam eden bir çarpımı ve bir sayacı izleyip ikisini bir demet olarak döndürüyoruz.

Her biri güncellenmiş değerini sonraki çağrıya aktarır.

def stats(xs: List[Int]): (Int, Int) = {
  def loop(rest: List[Int], prod: Int, count: Int): (Int, Int) =
    rest match {
      case Nil    => (prod, count)
      case h :: t => loop(t, prod * h, count + 1)
    }
  loop(xs, 1, 0)
}

Başlangıç Değerini Seçme

Başlangıç birikim değeri, işlemin etkisiz elemanı olmalıdır.

Toplama için 0, çarpma için 1, liste oluşturma için Nil, dizeleri birleştirme için boş dize kullanın.

Yanlış bir başlangıç değeri fark edilmeden yanlış sonuçlar üretir.

// addition  -> seed 0
// product   -> seed 1
// list      -> seed Nil
// string    -> seed ""

Sonuçların Sırası

Birikimli özyineleme öğeleri soldan sağa işler; ancak başa eklemeye dayalı birikim onları tersine çevirir.

Liste oluştururken sırayı korumanız gerekiyorsa sonunda reverse uygulayın veya sona ekleyin; ancak sona ekleme daha yavaştır. Önce başa ekleyip sonra tersine çevirme yaygın bir yaklaşımdır.

def mapInc(xs: List[Int]): List[Int] = {
  def loop(rest: List[Int], acc: List[Int]): List[Int] = rest match {
    case Nil    => acc.reverse
    case h :: t => loop(t, (h + 1) :: acc)
  }
  loop(xs, Nil)
}

Hızlı Kontrol

Birikimli özyineleme hakkındaki doğru ifadeyi seçin.

Özet

Birikim değişkeni devam eden sonucu özyinelemeli çağrılar boyunca aşağı taşır; böylece temel durum onu doğrudan döndürebilir.

Bu, özyinelemeli çağrının kuyruk konumunda olmasını sağlar ve Scala'nın kuyruk çağrısı iyileştirmesini ve @tailrec güvenlik denetimini etkinleştirir.

Birikim değişkenini işlemin etkisiz elemanıyla başlatın; sıra önemliyse sonunda tersine çevirin.

Sıkça Sorulan Sorular

“Birikim Kalıpları” dersi ücretsiz mi?

Evet — “Birikim Kalıpları” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Scala for Backend Engineering & Functional Programming kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Scala for Backend Engineering & Functional Programming kursu toplamda 4 dersten oluşur.

“Birikim Kalıpları” dersinde ne öğreneceğim?

Durumu özyineleme boyunca taşıyın. Scala for Backend Engineering & Functional Programming ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Scala for Backend Engineering & Functional Programming öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Scala for Backend Engineering & Functional Programming, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.

“Birikim Kalıpları” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Scala for Backend Engineering & Functional Programming dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Scala for Backend Engineering & Functional Programming dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. Özyinelemeli Düşünme
  2. Birikim Kalıpları
  3. foldLeft ve foldRight
  4. reduce ve aggregate
← Scala for Backend Engineering & Functional Programming Sayfasına Dön