2010-04-27 2 views
9

Так мое понимание выделки (на основе SO вопросов) является то, что она позволяет вам частично заданные параметры функции и возвращает «усеченную» функцию в качестве результата.Является ли currying просто способом избежать наследования?

Если у вас есть большая волосатая функция принимает 10 параметров и выглядит как

function (location, type, gender, jumpShot%, SSN, vegetarian, salary) { 
    //weird stuff 
} 

и вы хотите функцию «подмножество», что позволит вам иметь дело с предустановками для всех, кроме jumpShot%, не должны вам просто вырвать класс, который наследуется от исходной функции?

Я полагаю, что я ищу является примером использования этой модели. Благодаря!

ответ

1

В JavaScript я выделки на функции обратного вызова (потому что они не могут быть переданы любые параметры после того, как они называются (от вызывающего абонента)

Так что-то вроде:

... 
var test = "something specifically set in this function"; 
onSuccess: this.returnCallback.curry(test).bind(this), 

// This will fail (because this would pass the var and possibly change it should the function be run elsewhere 
onSuccess: this.returnCallback.bind(this,test), 
... 

// this has 2 params, but in the ajax callback, only the 'ajaxResponse' is passed, so I have to use curry 
returnCallback: function(thePassedVar, ajaxResponse){ 
    // now in here i can have 'thePassedVar', if 
} 

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

5

Currying has многие используют. pile, определяя параметры по умолчанию для функций, которые вы часто используете для возврата специализированных функций, которые служат определенной цели.

Но позвольте мне дать вам пример:

function log_message(log_level, message){} 
log_error = curry(log_message, ERROR) 
log_warning = curry(log_message, WARNING) 

log_message(WARNING, 'This would be a warning') 
log_warning('This would also be a warning') 
1

При программировании в функциональном стиле, часто связывают аргументы для создания новых функций (в данном примере, предикаты) от старого. Псевдо-код:

filter(bind_second(greater_than, 5), some_list) 

может быть эквивалентен:

filter({x : x > 5}, some_list) 

где {x : x > 5} является анонимным определением функции. То есть он строит список всех значений от some_list, которые больше 5.

0

Во многих случаях параметры, которые необходимо пропустить, во время компиляции не будут известны, а скорее во время выполнения. Кроме того, нет ограничений на количество делегатов в карри, которые могут существовать для данной функции. Ниже приводится адаптация из реальной программы.

У меня есть система, в которой я разослать командные пакеты на удаленную машину и получить обратно ответные пакеты. Каждый пакет команд имеет номер индекса, и каждый ответ содержит номер индекса команды, для которого он является ответом. Типичная команда, переведенная на английский язык, может быть «дать мне 128 байт, начиная с адреса 0x12300». Типичный ответ может быть «Успешным». наряду с 128 байтами данных.

Для обработки связи, у меня есть рутина, которая принимает ряд командных пакетов, каждый из которых с делегатом. По мере получения каждого ответа соответствующий делегат будет запущен на полученных данных. Делегат, связанный с приведенной выше командой, будет похож на «Подтвердите, что я получил« успех »с 128 байтами данных, и если да, сохраните их в моем буфере по адресу 0x12300». Обратите внимание, что несколько пакетов могут быть выдающимися в любой момент времени; для того, чтобы подпрограмма знала, куда должны поступать входящие данные, необходимо указать параметр адресной валюты.Даже если бы я хотел написать процедуру «хранить данные в буфер», которая не требовала адресного параметра, она не имела бы способа узнать, куда должны поступать входящие данные.

Смежные вопросы