2011-08-09 11 views
5

immutable.Set için tanımlanır:Scala'da neden katlama tipi var? Yol kat bakıyordu

def fold [A1 >: A] (z: A1)(op: (A1, A1) ⇒ A1): A1 

henüz foldLeft olarak tanımlanır:

def foldLeft [B] (z: B)(op: (B, A) ⇒ B): B 

Bu günümüze dek, en azından ilk bakışta, benim için garip görünüyor foldLeft'in yaptığı gibi geri döndüğü koleksiyonun türünü değiştirebilmek için katlamayı bekliyordu.

Bunun sebebi, katlama ve katlama özelliklerinin, katların katlandığı sırayla ilgili bir şey garanti etmesinden kaynaklanmaktadır. Katlama ile verilen garanti nedir?

+0

Jean-Philippe'in cevabı size yardım ediyor mu? Bkz. Http://stackoverflow.com/questions/6253978/difference-between-fold-and-foldleft-or-foldright –

+0

Bir bakıma, sanırım. Katmanın, toplama API'sinde katlanmadan farklı bir sonuç döndüreceği bir durum görmedim, ancak sanırım bu ayrımın gerekli olduğu bazı uygulamaların var olabileceğini tahmin ediyorum. Bağlantı için teşekkürler. –

cevap

6

foldLeft'u uygularken, başlangıç ​​değeriniz ilk liste öğesiyle birleştirilir. Sonuç, ikinci liste elemanı ile birleştirilmiştir. Bu sonuç ile üçüncü ve benzerleri. Sonunda, liste başlangıç ​​değerinizden aynı türde bir öğeye çöktü. Bu nedenle, işleviniz tarafından bir liste öğesiyle birleştirilebilecek bazı türlere ihtiyacınız vardır.
foldRight için de aynısı geçerlidir, ancak ters sırada.

fold, bu kombinasyonun tamamlandığı siparişin verilmesini garanti etmez. Ve tek bir pozisyonda başladığını garanti etmez. Kıvrımlar paralel olabilir. Paralelizme sahip olabileceğiniz için, herhangi bir 2 liste elemanının veya dönüş değerinin birleştirilmesi gerekir - bu, türlere bir kısıtlama getirir.

Bir davayı görmeniz gerektiğini düşündüğünüz yorumunuzla ilgili olarak bir etkiye sahip olmanız gerekiyor: Karakterlerin bir listesini birleştirmek için katlamalarınızı kullandığınızı ve sonuç olarak bir metnin olmasını istediğinizi varsayalım. Girişiniz A, B, C ise, büyük olasılıkla ACB (örneğin) yerine ABC almak için siparişi korumak istersiniz.
Diğer yandan, sadece sayıları topladığınız takdirde, siparişin önemi yoktur. 1, 2, 3 toplanması, eklerin siparişinden bağımsız olarak 6 değerini verir. Bu gibi durumlarda, foldLeft veya foldRight yerine fold kullanılması daha hızlı yürütülmesine yol açabilir.

+0

Teşekkürler. Düzenin önemli olduğunu düşünmüştüm, ama asla paralellik düşünmedim. –

0

Görünüşe göre FoldLeft B'ye dönmelidir. Yöntem bir B argümanı alır - bu bir akümülatördür. A değerleri, "B'ye daha fazla" eklemek için kullanılır. Son birikmiş değer döndürülür. FoldLeft ve FoldRight'ın bu açıdan aynı olduğunu düşünüyorum.