Her yöntem için sadece bir parametre gerektiren zincirleme yöntemler, körelemeye eşdeğer midir?


15

Son zamanlarda Ruby ile oynuyorum ve kendimi saf nesne yönelimli dillerde (ve saf olmayanlar bile) sadece bir parametre alan ve daha sonra bir araya getirilen yöntemlerin yapılıp yapılmadığını merak ederek buldum. tarzı? Değilse, neden olmasın? Konuyla ilgili ayrıntılı, hatta titiz bir cevabı takdir ediyorum.

Yanıtlar:


14

Nesneye yönelik dillerde yöntem zincirleme, körelemekten biraz farklıdır. Tarafından tanımı , son-işlemden sonucu, orijinal için daha sınırlı bir şeklidir fonksiyonu . Tarafından esası , yöntem zincirleme sonucu, orijinal (genellikle işlev olmayan) bir değiştirilmiş formdaki bir nesne . Metot zincirleme, aynı sınıftaki ilgisiz metotlarla kullanılabilirken, curry işlemi, orijinal fonksiyonun bir veya daha fazla parametresinin sabitlendiği (önceden belirlenmiş) bir fonksiyonun geri döndürülmesini içerir.

Java'da yöntem zincirleme aşağıdaki gibidir:

String myString = new StringBuilder("Hi ").append(firstName)
                                          .append(" ")
                                          .append(lastName)
                                          .append("!")
                                          .toString();

Bu nedenle, bu .append () yöntemi çağrılarının her biri, anonim StringBuilder nesnesine bir işaretçi döndürür. Bu nesne, her .append () öğesinden sonra tamamlanır ve bir işlev değildir.

Aksine, Scala'da kısmi uygulama veya körleme şöyle:

def simple(x:Int, y:Int, z:Int) = x * (y + z)
val simpler = simple(2, _:Int, _:Int)
simpler(3, 4) => 14

(Örnek Daniel Yankowsky'nin blogundan alınmıştır )

simpler()bu örnekte için bir sarmalayıcı işlevidir simple(). simpler()hala daha sınırlı bir versiyonundan başka bir şeyi değerlendirmeden önce daha fazla parametre alan bir işlevdir.

EDIT: Bunu bir gün sonra okumak, "sarmalayıcı-işlev" anahtarı olduğunu düşünüyorum. Körelme veya kısmi uygulama Java'da en iyi sarma yöntemleriyle simüle edilebilir.

public interface Simpler {
    public int apply(int y, int z);
}

public class Simple {
    public int apply(int x, int y, int z) { return x * (y + z); }

    public Simpler partiallyApply(final int x) {
        final simple = this;
        return new Simpler() {
            @Override
            public int apply(int y, int z) {
                // x is the final int parameter to partiallyApply()
                simple.apply(x, y, z);
            }
        }
    }
}

: SON-DÜZENLEME

Yöntem zincirleme, kısmi uygulamaya veya köriye benzer olabilir, ancak yalnızca diğer yöntemleri döndüren yöntemlerle eşdeğer olabilir (Functors'a bakın) ve daha sonra yöntemlerin, köri veya kısmi uygulamayı anlamlı bir şekilde modellenen dönüş tipleriyle ayarlanması gerekir.

Metot zincirleme, "Builder" tasarım deseni ve Java 8'deki yeni Koleksiyonlar Kütüphanesi arayüzlerinde yapıldığı gibi, tembel değerlendirme gibi bir şeyi uygulamak için daha sık kullanılır .

Umarım bu yardımcı olur.


+1: Bunu biliyordum, ama senin kadar yakın bir yerde ifade edebileceğimi sanmıyorum.
Peter Rowell

Güzel açıkladı, işte yeşil bir onay işareti ve sorununuz için bir yukarı oy.
Dünya Mühendisi

StringBuilder'ın çok güzel bir örneği hakkında soru - toString()çağrı olmadan, çağrımızda körükleme niyetini etkili bir şekilde çoğaltmıyor muyuz? Sadece OO'da köri kavramını düzleştirmeye çalışıyorum.
Sridhar Sarnobat

1
@ Sridhar-Sarnobat curried bir fonksiyon daha az parametreli başka bir fonksiyon döndürür. Elenen parametreler, döndürülen işlevde dahili sabitlere dönüştürülür. Bazı nesnelere Java 8'deki işlevler gibi davranılır, bu da kafa karıştırıcı olabilir, ancak StringBuilder bunlardan biri değildir. Hmm, StringBuilder append(charSeq)içinde, insert(destOffset, charSeq)işlev destOffsether zaman StringBuilder uzunluğunun bulunduğu işlevin curved bir şeklidir .
GlenPeterson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.