Является ли «Частичное применение функции» неправильным в контексте Javascript? - PullRequest
11 голосов
/ 18 сентября 2008

Мой друг и я обсуждали карри и применение частичных функций в Javascript, и мы пришли к совершенно разным выводам относительно того, достижимы ли они. Я придумал эту реализацию Function.prototype.curry, которая была основой нашего обсуждения:

Function.prototype.curry = function() {
    if (!arguments.length) return this;

    var args = Array.prototype.slice.apply(arguments);
    var mmm_curry = this, args;

    return function() {
        var inner_args = Array.prototype.slice.apply(arguments);
        return mmm_curry.apply(this, args.concat(inner_args));
    }

}

Что используется следующим образом:

var vindaloo = function(a, b) {
    return (a + b);
}

var karahi = vindaloo.curry(1);
var masala = karahi(2);
var gulai = karahi(3);

print(masala);
print(other);

Вывод которого выглядит следующим образом в Spidermonkey:

$ js curry.js
3
4

Он считал, что, поскольку примитив Javascript function изначально не поддерживает "частичное применение функции", совершенно неправильно ссылаться на функцию, связанную с переменной karahi, как частично примененную. Его аргумент состоял в том, что когда функция vindaloo каррируется, сама функция полностью применяется и возвращается замыкание, а не «частично примененная функция».

Теперь, по моему мнению, хотя сам Javascript не обеспечивает поддержку частичного применения в его function примитивах (в отличие от, скажем, ML или Haskell), это не означает, что вы не можете создать функцию более высокого порядка язык, который способен инкапсулировать понятие частично прикладной функции. Кроме того, несмотря на то, что функция «применена», область действия функции по-прежнему связана с возвращаемым ей замыканием, в результате чего она остается «частично примененной».

Что правильно?

Ответы [ 5 ]

3 голосов
/ 18 сентября 2008

Я думаю, что вполне нормально говорить о применении частичных функций в JavaScript - если он работает как частичное приложение, то он должен Будь один. Как еще вы бы назвали это?

Как ваша curry функция достигает своей цели - это просто реализация подробно. Подобным образом мы могли бы частично применить в спецификации ECMAScript, но когда IE будет реализовывать это так же, как вы, вы бы нет способа узнать.

3 голосов
/ 18 сентября 2008

Технически вы создаете совершенно новую функцию, которая вызывает оригинальную функцию. Так что, если я правильно понимаю частично примененные функции, это не частично примененная функция. Частично примененная функция будет ближе к этому (обратите внимание, что это не общее решение):

vindaloo.curry = function(a) {
    return function(b) {
        return a + b;
    };
};

IIUC, это все еще не будет частично примененная функция. Но это ближе. Истинно частично примененная функция на самом деле будет выглядеть так, если вы сможете проверить код:

function karahi(b) {
    return 1 + b;
};

Итак, технически, ваш оригинальный метод это , просто возвращающий функцию, связанную внутри замыкания. Единственный способ по-настоящему частично применить функцию в JavaScript - это проанализировать функцию, применить изменения и затем запустить ее через eval ().

Тем не менее, ваше решение является хорошим практическим приложением концепции к JavaScript, так что, практически говоря, достигается цель, даже если она не технически точна.

1 голос
/ 18 сентября 2008

Технические детали не имеют значения для меня - если семантика остается той же самой, и, для всех намерений и целей, функция действует так, как если бы она была действительно частично примененной функцией, кого это волнует?

Раньше я был настолько академичным в вопросах, но беспокойство о таких подробностях в конце концов не сделало реальной работы.

Лично я пользуюсь MochiKit ; у него есть хорошая функция part (), которая помогает создавать такие. Я люблю это.

0 голосов
/ 01 апреля 2016

По его мнению, поскольку примитив функции Javascript изначально не поддерживает "приложение с частичной функцией"

Вы можете сделать карри в ES6 довольно элегантно:

> const add = a => b => a + b
> const add10 = add(10)
> [1,2,3].map(add10)
[ 11, 12, 13 ]
0 голосов
/ 18 сентября 2008

Вы должны проверить Функции Curried JavaScript . Я не полностью обернул голову вокруг его функции карри, но он может иметь ваш ответ.

Редактировать: Я бы согласился с вашей оценкой, однако.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...