Apakah metode dirantai yang hanya membutuhkan satu parameter per metode setara dengan currying?

15

Saya telah bermain-main dengan Ruby akhir-akhir ini dan saya mendapati diri saya bertanya-tanya apakah dalam bahasa berorientasi objek murni (dan bahkan yang tidak murni) membuat metode yang hanya mengambil satu parameter dan kemudian dirantai bersama sama dengan menjelajah dalam bahasa dengan fungsional gaya? Jika tidak, mengapa tidak? Saya menghargai jawaban terperinci, bahkan keras tentang masalah ini.

Insinyur Dunia
sumber

Jawaban:

14

Metode chaining dalam bahasa berorientasi objek sedikit berbeda dari currying. Menurut definisi , hasil currying adalah bentuk yang lebih terbatas dari fungsi aslinya . Dengan konvensi , hasil dari metode chaining adalah bentuk modifikasi dari aslinya (biasanya non-fungsi) objek . Metode chaining dapat digunakan dengan metode yang tidak terkait pada kelas yang sama, sedangkan currying melibatkan mengembalikan fungsi di mana satu atau lebih parameter fungsi asli diperbaiki (ditentukan sebelumnya).

Di Jawa, metode chaining seperti:

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

Jadi, masing-masing panggilan metode .append () mengembalikan pointer ke objek StringBuilder anonim. Objek ini selesai setelah masing-masing. Append (), dan itu bukan fungsi.

Sebaliknya, dalam Scala, aplikasi sebagian atau currying seperti:

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

(Sampel diambil dari blog Daniel Yankowsky )

simpler()dalam contoh ini adalah fungsi wrapper untuk simple(). simpler()masih merupakan fungsi yang membutuhkan lebih banyak parameter sebelum dapat mengevaluasi apa pun kecuali versi yang lebih terbatas.

EDIT: Membaca ini sehari kemudian, saya pikir "fungsi wrapper" adalah kuncinya. Aplikasi kari atau parsial mungkin paling baik disimulasikan di Jawa dengan metode wrapper.

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);
            }
        }
    }
}

: AKHIR-EDIT

Metode chaining dapat mirip dengan aplikasi parsial atau currying, tetapi hanya bisa setara dengan metode yang mengembalikan metode lain (mencari Functors), dan kemudian metode perlu diatur dengan tipe-tipe return yang berarti memodelkan currying atau aplikasi parsial.

Metode chaining lebih sering digunakan untuk mengimplementasikan sesuatu seperti evaluasi malas, seperti yang dilakukan dengan pola desain "Builder" dan antarmuka Perpustakaan Koleksi baru di Jawa 8 .

Saya harap itu membantu.

GlenPeterson
sumber
+1: Saya tahu itu, tapi saya rasa saya tidak bisa mengartikulasikannya di dekat Anda.
Peter Rowell
Dijelaskan dengan baik, ini tanda centang hijau dan jawaban atas masalah Anda.
Insinyur Dunia
Pertanyaan tentang contoh StringBuilder yang sangat bagus - tanpa toString()panggilan, apakah kita tidak secara efektif meniru maksud menjelajah panggilan kita? Saya hanya mencoba untuk mendapatkan konsep currying in OO straight.
Sridhar Sarnobat
1
@ Sridhar-Sarnobat fungsi kari mengembalikan fungsi lain dengan lebih sedikit parameter. Parameter yang dihilangkan diubah menjadi konstanta internal pada fungsi yang dikembalikan. Beberapa objek diperlakukan seperti fungsi di Java 8, yang dapat membuat ini membingungkan, tetapi StringBuilder bukan salah satunya. Hmm, di dalam StringBuilder, append(charSeq)fungsinya adalah bentuk kari dari insert(destOffset, charSeq)fungsi di mana destOffsetselalu panjang StringBuilder.
GlenPeterson