Чи є ланцюгові методи, для яких потрібен лише один параметр на метод, еквівалентний кришці?


15

Останнім часом я бавляюся з Рубі, і мені стало цікаво, чи в чистих об'єктно-орієнтованих мовах (і навіть тих, які не є чистими) виготовлення методів, які беруть лише один параметр, а потім зв'язані між собою, еквівалентно закріпленню в мовах з функціоналом стиль? Якщо ні, то чому б і ні? Буду вдячний за детальну, навіть сувору відповідь на цю тему.

Відповіді:


14

Метод ланцюжка в об'єктно-орієнтованих мовах мало чим відрізняється від карі. За визначенням , результат currying є більш обмеженою формою вихідної функції . За умовою , результат ланцюга методів - це змінена форма вихідного (як правило, нефункціонального) об'єкта . Ланцюжок методів може використовуватися з неспорідненими методами одного класу, тоді як currying включає повернення функції, де один або більше параметрів вихідної функції закріплені (заздалегідь визначені).

У Java ланцюжок методів такий:

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

Отже, кожен із цих методів .append () повертає покажчик на анонімний об'єкт StringBuilder. Цей об'єкт є завершеним після кожного .append (), і це не функція.

Навпаки, у Scala часткове нанесення або висипання виглядає так:

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

(Зразок взято з блогу Даніеля Янковського )

simpler()у цьому прикладі є функція обгортки для simple(). simpler()все ще функція, яка приймає більше параметрів, перш ніж вона зможе оцінити будь-що, крім більш обмеженої версії себе.

EDIT: Читаючи це через день, я думаю, що "функція обгортки" є ключовою. Заготівля або часткове застосування найкраще змоделювати на Java методами обгортки.

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

: END-EDIT

Ланцюг методів може бути подібний до часткового нанесення або каррінгу, але він може бути еквівалентним лише методам, які повертають інші методи (шукайте функціонерів), і тоді методи повинні бути налаштовані з типом повернення, які змістовно моделюють currying або часткове застосування.

Ланцюжок методів частіше використовується для реалізації чогось подібного до ледачого оцінювання, як це робиться з дизайнерською схемою "Builder" та новими інтерфейсами бібліотеки колекцій на Java 8 .

Я сподіваюся, що це допомагає.


+1: Я це знав, але не думаю, що я міг би сформулювати це десь поруч, як ви.
Пітер Роуелл

Чудово пояснено, ось зелена галочка та підказка для ваших проблем.
Світовий інженер

Питання про дуже приємний приклад StringBuilder - без toString()виклику чи не ефективно ми повторюємо намір висловитись у своєму дзвінку? Я просто намагаюся зрозуміти поняття currying в OO прямо.
Шрідхар Сарнобат

1
@ Шрідхар-Сарнобат крива функція повертає іншу функцію з меншими параметрами. Усунені параметри перетворюються на внутрішні константи у поверненій функції. Деякі об'єкти трактуються як функції в Java 8, що може зробити це заплутаним, але StringBuilder не є одним з них. Гм, всередині StringBuilder append(charSeq)функція - це крива форма insert(destOffset, charSeq)функції, де destOffsetзавжди є довжина StringBuilder.
GlenPeterson
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.