Что такое «карри»? - PullRequest
       96

Что такое «карри»?

585 голосов
/ 31 августа 2008

Я видел ссылки на функции карри в нескольких статьях и блогах, но не могу найти хорошее объяснение (или хотя бы одно, которое имеет смысл!)

Ответы [ 15 ]

3 голосов
/ 30 августа 2009

Я нашел эту статью и статью, на которую она ссылается, полезной, чтобы лучше понять карри: http://blogs.msdn.com/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx

Как уже упоминалось, это просто способ иметь функцию с одним параметром.

Это полезно, поскольку вам не нужно предполагать, сколько параметров будет передано, поэтому вам не нужны функции с двумя, тремя и четырьмя параметрами.

2 голосов
/ 18 апреля 2018

Как и все остальные ответы, карри помогает создавать частично примененные функции. Javascript не предоставляет встроенную поддержку автоматического карри. Поэтому приведенные выше примеры могут не помочь в практическом кодировании. В LifeScript есть отличный пример (который по сути компилируется в js) http://livescript.net/

times = (x, y) --> x * y
times 2, 3       #=> 6 (normal use works as expected)
double = times 2
double 5         #=> 10

В приведенном выше примере, когда вы указали меньше аргументов, liveScript генерирует для вас новую карри-функцию (double)

2 голосов
/ 11 апреля 2016

Примером каррирования может служить ситуация, когда у вас есть функции, о которых вы знаете только один из параметров:

Например:

func aFunction(str: String) {
    let callback = callback(str) // signature now is `NSData -> ()`
    performAsyncRequest(callback)
}

func callback(str: String, data: NSData) {
    // Callback code
}

func performAsyncRequest(callback: NSData -> ()) {
    // Async code that will call callback with NSData as parameter
}

Здесь, поскольку вы не знаете второй параметр для обратного вызова при отправке его на performAsyncRequest(_:), вам придется создать еще одну лямбду / замыкание, чтобы отправить его в функцию.

2 голосов
/ 04 мая 2014

Функция карри применяется к нескольким спискам аргументов, а не просто один.

Вот обычная функция без карри, которая добавляет два Int параметры, х и у:

scala> def plainOldSum(x: Int, y: Int) = x + y
plainOldSum: (x: Int,y: Int)Int
scala> plainOldSum(1, 2)
res4: Int = 3

Вот аналогичная функция, которая карри. Вместо из одного списка из двух параметров Int, вы применяете эту функцию к двум спискам одного Параметр Int каждый:

scala> def curriedSum(x: Int)(y: Int) = x + y
curriedSum: (x: Int)(y: Int)Intscala> second(2)
res6: Int = 3
scala> curriedSum(1)(2)
res5: Int = 3

То, что здесь происходит, заключается в том, что когда вы вызываете curriedSum, вы фактически получаете два традиционных вызова функций друг за другом. Первая функция вызов принимает один параметр Int с именем x и возвращает функцию значение для второй функции. Эта вторая функция принимает параметр Int y.

Вот функция с именем first, которая по духу делает то, что первый традиционный вызов функции curriedSum будет делать:

scala> def first(x: Int) = (y: Int) => x + y
first: (x: Int)(Int) => Int

Применение 1 к первой функции - другими словами, вызов первой функции и передача в 1 - дает вторую функцию:

scala> val second = first(1)
second: (Int) => Int = <function1>

Применение 2 ко второй функции дает результат:

scala> second(2)
res6: Int = 3
0 голосов
/ 16 сентября 2018

Здесь вы можете найти простое объяснение реализации карри в C #. В комментариях я постарался показать, насколько полезно карри:

public static class FuncExtensions {
    public static Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(this Func<T1, T2, TResult> func)
    {
        return x1 => x2 => func(x1, x2);
    }
}

//Usage
var add = new Func<int, int, int>((x, y) => x + y).Curry();
var func = add(1);

//Obtaining the next parameter here, calling later the func with next parameter.
//Or you can prepare some base calculations at the previous step and then
//use the result of those calculations when calling the func multiple times 
//with different input parameters.

int result = func(1);
...