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


653

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


12
[Оставлено в качестве комментария, поскольку это будет бесполезно для нематематиков.] Согласно определению декартовой замкнутой категории, существует фиксированное семейство присоединений (естественно параметризованных A) между X -> X x A и X -> X ^ A. Изоморфизмы hom (X x A, Y) <-> hom (X, Y ^ A) являются curryи uncurryфункциями Хаскелла. Здесь важно то, что эти изоморфизмы фиксированы заранее и поэтому «встроены» в язык.
Александр К.

3
Здесь есть хороший учебник для каррирования в haskell learnyouahaskell.com/higher-order-functions#curried-functions. Короткие комментарии о том, что add x y = x+y(curried) отличается от add (x, y)=x+y(uncurried)
Jaider

Ответы:


872

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

function add (a, b) {
  return a + b;
}

add(3, 4); // returns 7

Это функция, которая принимает два аргумента, a и b, и возвращает их сумму. Теперь мы будем карри эту функцию:

function add (a) {
  return function (b) {
    return a + b;
  }
}

Это функция, которая принимает один аргумент, a, и возвращает функцию, которая принимает другой аргумент, b, и эта функция возвращает их сумму.

add(3)(4);

var add3 = add(3);

add3(4);

Первый оператор возвращает 7, как оператор add (3, 4). Второе утверждение определяет новую функцию с именем add3, которая добавит 3 к своему аргументу. Это то, что некоторые люди могут назвать закрытием. Третье утверждение использует операцию add3 для добавления 3 к 4, в результате чего снова получается 7.


236
В практическом смысле, как я могу использовать эту концепцию?
Клубника

43
@Strawberry, скажем, например, что у вас есть список чисел в, [1, 2, 3, 4, 5]который вы хотите умножить на произвольное число. В Haskell я могу написать, map (* 5) [1, 2, 3, 4, 5]чтобы умножить весь список 5, и таким образом генерировать список [5, 10, 15, 20, 25].
nyson

62
Я понимаю, что делает функция карты, но я не уверен, что понимаю смысл, который вы пытаетесь проиллюстрировать для меня. Вы говорите, что функция карты представляет концепцию карри?
Клубника

78
@Strawberry Первым аргументом mapдолжна быть функция, которая принимает только 1 аргумент - элемент из списка. Умножение - как математическая концепция - является бинарной операцией; требуется 2 аргумента. Однако в Haskell *есть функция карри, аналогичная второй версии addв этом ответе. Результатом (* 5)является функция, которая принимает один аргумент и умножает его на 5, что позволяет нам использовать его с картой.
Довал

26
@Strawberry Хорошая особенность функциональных языков, таких как Standard ML или Haskell, заключается в том, что вы можете получить карри "бесплатно". Вы можете определить функцию с несколькими аргументами так же, как и в любом другом языке, и вы автоматически получите ее версию с карри, без необходимости самим добавлять кучу лямбд. Таким образом, вы можете создавать новые функции, которые принимают меньше аргументов от любой существующей функции без особых хлопот и беспокойств, и это позволяет легко передавать их другим функциям.
Довал

125

В алгебре функций иметь дело с функциями, которые принимают несколько аргументов (или эквивалентный один аргумент, который является N-кортежем), несколько неэлегантно, но, как доказал Моисей Шенфинкель (и, независимо, Хаскелл Карри), это не нужно: все, что вам нужно нужны функции, которые принимают один аргумент.

Итак, как вы справляетесь с тем, что, естественно, выражаете, скажем f(x,y),? Ну, вы воспринимаете это как эквивалент f(x)(y)- f(x), вызываете его g, это функция, и вы применяете эту функцию к y. Другими словами, у вас есть только функции, которые принимают один аргумент - но некоторые из этих функций возвращают другие функции (которые также принимают один аргумент ;-).

Как обычно, в Википедии есть хорошая сводка об этом, с множеством полезных указателей (вероятно, включая те, которые касаются ваших любимых языков ;-), а также немного более строгой математической обработки.


1
Я полагаю, что аналогичный мой комментарий выше - я не видел, чтобы функциональные языки ограничивали функции одним аргументом. Я ошибаюсь?
Эрик М

1
@hoohoo: функциональные языки обычно не ограничивают функции одним аргументом. Однако на более низком, более математическом уровне гораздо проще иметь дело с функциями, которые принимают только один аргумент. (Например, в лямбда-исчислении функции принимают только один аргумент за раз.)
Сэм ДеФаббиа-Кейн

1
ХОРОШО. Тогда еще вопросы. Является ли следующее утверждение верным? Лямбда-исчисление может использоваться в качестве модели функционального программирования, но функциональное программирование не обязательно применяется к лямбда-исчислению.
Эрик М

7
Как отмечают страницы википедии, большинство языков FP «украшают» или «увеличивают» лямбда-исчисление (например, с некоторыми константами и типами данных), а не просто «применяют» его, но это не так близко. Кстати, что создает у вас впечатление, что, например, Haskell не «ограничивает функции принятием одного аргумента»? Это действительно так, хотя это не имеет значения благодаря карри; например div :: Integral a => a -> a -> a- обратите внимание на эти множественные стрелки? «Отобразить a на функцию, отображающую a на a» - одно чтение ;-) Вы могли бы использовать (единственный) аргумент кортежа для div& c, но это было бы действительно не-идиоматично в Haskell.
Алекс Мартелли

@Alex - по поводу Haskell & arg count, я не провел много времени на Haskell, и это было всего несколько недель назад. Так что сделать ошибку было легко.
Эрик М

101

Вот конкретный пример:

Предположим, у вас есть функция, которая вычисляет гравитационную силу, действующую на объект. Если вы не знаете формулу, вы можете найти ее здесь . Эта функция принимает в качестве аргументов три необходимых параметра.

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


2
Любопытно, что библиотека Prototype для JavaScript предлагает функцию «карри», которая в точности соответствует тому, что вы объяснили здесь: prototypejs.org/api/function/curry
shuckster

Новая функция PrototypeJS для карри. prototypejs.org/doc/latest/language/Function/prototype/curry/…
Ричард Айот

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

9
@neontapir правильно. То, что описал Ши, не является карри. Это частичное применение. Если функция с тремя аргументами каррируется, и вы называете ее как f (1), то вы получаете не функцию с двумя аргументами. Вы получаете функцию с одним аргументом, которая возвращает другую функцию с одним аргументом. Функция карри может быть передана только один аргумент. Функция карри в PrototypeJS также не карри. Это частичное применение.
MindJuice

нет (для частичной оценки) и нет (для карри). это известно как частичное применение. карри необходимо, чтобы включить его.
Уилл Несс

47

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

Например, в F # вы можете определить функцию следующим образом:

let f x y z = x + y + z

Здесь функция f принимает параметры x, y и z и суммирует их вместе так:

f 1 2 3

Возвращает 6.

Поэтому из нашего определения мы можем определить функцию карри для f: -

let curry f = fun x -> f x

Где fun x -> fx - лямбда-функция, эквивалентная x => f (x) в C #. Эта функция вводит функцию, которую вы хотите каррировать, и возвращает функцию, которая принимает один аргумент и возвращает указанную функцию с первым аргументом, установленным для входного аргумента.

Используя наш предыдущий пример, мы можем получить карри f таким образом:

let curryf = curry f

Затем мы можем сделать следующее:

let f1 = curryf 1

Который дает нам функцию f1, которая эквивалентна f1 yz = 1 + y + z. Это означает, что мы можем сделать следующее:

f1 2 3

Который возвращает 6.

Этот процесс часто путают с «частичным применением функции», которое можно определить следующим образом:

let papply f x = f x

Хотя мы можем расширить его до нескольких параметров, а именно:

let papply2 f x y = f x y
let papply3 f x y z = f x y z
etc.

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

let f1 = f 1
f1 2 3

Который вернет результат 6.

В заключении:-

Разница между карри и частичным применением функции заключается в том, что:

Карринг берет функцию и предоставляет новую функцию, принимающую один аргумент и возвращающую указанную функцию с первым аргументом, установленным для этого аргумента. Это позволяет нам представлять функции с несколькими параметрами в виде серии функций с одним аргументом . Пример:-

let f x y z = x + y + z
let curryf = curry f
let f1 = curryf 1
let f2 = curryf 2
f1 2 3
6
f2 1 3
6

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

let f x y z = x + y + z
let f1 = f 1
let f2 = f 2
f1 2 3
6
f2 1 3
6

Таким образом, методы в C # должны быть карри, прежде чем они могут быть применены частично?
cdmckay

«Это позволяет нам представлять функции с несколькими параметрами в виде серии функций с одним аргументом» - идеально, это хорошо для меня прояснилось. Спасибо
Нечеткий анализ

44

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

В JavaScript:

let add = function(x){
  return function(y){ 
   return x + y
  };
};

Позвольте нам назвать это так:

let addTen = add(10);

Когда это выполняется, 10передается как x;

let add = function(10){
  return function(y){
    return 10 + y 
  };
};

что означает, что нам возвращается эта функция:

function(y) { return 10 + y };

Поэтому, когда вы звоните

 addTen();

Вы действительно звоните:

 function(y) { return 10 + y };

Итак, если вы сделаете это:

 addTen(4)

это так же, как:

function(4) { return 10 + 4} // 14

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

let addTwo = add(2)       // addTwo(); will add two to whatever you pass in
let addSeventy = add(70)  // ... and so on...

Теперь очевидный последующий вопрос заключается в том, почему на земле вы когда-нибудь хотели бы это сделать? Он превращает то, что было нетерпеливой операцией, x + yв операцию, которую можно выполнить лениво, что означает, что мы можем сделать, по крайней мере, две вещи: 1. кэшировать дорогие операции; 2. достичь абстракций в функциональной парадигме.

Представьте, что наша функция карри выглядит так:

let doTheHardStuff = function(x) {
  let z = doSomethingComputationallyExpensive(x)
  return function (y){
    z + y
  }
}

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

let finishTheJob = doTheHardStuff(10)
finishTheJob(20)
finishTheJob(30)

Мы можем получить абстракции аналогичным образом.


5
Лучшее пошаговое объяснение по своей сути последовательного процесса, которое я видел здесь, и, возможно, лучший, самый объяснительный ответ из всего.

4
@jonsilver Я бы сказал наоборот, не очень хорошее объяснение. Я согласен, что хорошо объяснять приведенный пример, но люди склонны думать по умолчанию: «Да, совершенно ясно, но я мог бы сделать то же самое по-другому, так что хорошего в карри?» Другими словами, я бы хотел, чтобы у него было достаточно контекста или объяснения, чтобы осветить не только то, как работает карри, но и почему это не бесполезное и тривиальное наблюдение по сравнению с другими способами добавления десяти.
Whitneyland

29

Функция карри - это функция нескольких аргументов, переписанная так, что она принимает первый аргумент и возвращает функцию, которая принимает второй аргумент и так далее. Это позволяет функциям нескольких аргументов частично применять некоторые из своих начальных аргументов.


5
«Это позволяет функциям нескольких аргументов частично применять некоторые из своих начальных аргументов». - почему это выгодно?
Acarlon

5
@acarlon Функции часто вызываются неоднократно с одним или несколькими одинаковыми аргументами. Например, если вы хотите mapиспользовать функцию fнад списком списков, xssвы можете это сделать map (map f) xss.
Джон Харроп

1
Спасибо, это имеет смысл. Я сделал немного больше чтения, и оно стало на свои места.
2013 г.

4
Я думаю, что этот ответ делает это правильно в хорошем кратком изложении. «Curry» - это процесс получения функции нескольких аргументов и преобразования ее в серьезную из функций, каждая из которых принимает один аргумент и возвращает функцию с одним аргументом, или, в случае конечной функции, возвращает фактический результат. , Это может быть сделано для вас автоматически с помощью языка, или вы можете вызвать функцию curry () на других языках для генерации версии с карри. Обратите внимание, что вызов функции с каррированием с параметром не является каррированием. Карри уже произошло.
MindJuice

7

Вот игрушечный пример на Python:

>>> from functools import partial as curry

>>> # Original function taking three parameters:
>>> def display_quote(who, subject, quote):
        print who, 'said regarding', subject + ':'
        print '"' + quote + '"'


>>> display_quote("hoohoo", "functional languages",
           "I like Erlang, not sure yet about Haskell.")
hoohoo said regarding functional languages:
"I like Erlang, not sure yet about Haskell."

>>> # Let's curry the function to get another that always quotes Alex...
>>> am_quote = curry(display_quote, "Alex Martelli")

>>> am_quote("currying", "As usual, wikipedia has a nice summary...")
Alex Martelli said regarding currying:
"As usual, wikipedia has a nice summary..."

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

Редактирование добавить:

См. Http://docs.python.org/library/functools.html?highlight=partial#functools.partial , где также показано различие между частичным объектом и функцией в том, как Python реализует это.


Я не понимаю - вы делаете это: >>> am_quote = curry (display_quote, "Alex Martelli"), но затем вы делаете это следующим образом: >>> am_quote ("curry", "Как обычно, в Википедии есть хорошая сводка. .. ") Итак, у вас есть функция с двумя аргументами. Казалось бы, карри должен дать вам три разных функции, которые вы бы сочинили?
Eric M

Я использую частичное для каррирования только одного параметра, получая функцию с двумя аргументами. Если вы хотите, вы можете еще более карри am_quote, чтобы создать тот, который цитирует Алекса только по определенной теме. Математическое задание может быть сосредоточено на том, чтобы в конечном итоге получить функции только с одним параметром, но я считаю, что фиксирование любого количества параметров, как это обычно (если неточно с математической точки зрения) называется каррированием.
Anon

(кстати, '>>>' - это подсказка в интерактивном интерпретаторе Python, а не часть кода.)
Anon

ОК, спасибо за разъяснения по поводу аргументов. Я знаю о приглашении интерпретатора Python, я пытался процитировать строки, но это не сработало ;-)
Eric M

После вашего комментария я искал и нашел другие ссылки, в том числе здесь, на SO, на разницу между «curry» и. «частичное применение» в ответ на множество случаев неточного использования, с которым я знаком. См. Например: stackoverflow.com/questions/218025/…
Anon

5

Curry переводит функцию из вызываемой f(a, b, c)в вызываемую, как f(a)(b)(c).

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

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

Карринг не вызывает функцию. Это просто трансформирует его.

Давайте создадим функцию карри, которая выполняет каррирование для функций с двумя аргументами. Другими словами, curry(f)для двух аргументов f(a, b)переводится вf(a)(b)

function curry(f) { // curry(f) does the currying transform
  return function(a) {
    return function(b) {
      return f(a, b);
    };
  };
}

// usage
function sum(a, b) {
  return a + b;
}

let carriedSum = curry(sum);

alert( carriedSum(1)(2) ); // 3

Как видите, реализация представляет собой серию оболочек.

  • Результатом curry(func)является обертка function(a).
  • Когда он вызывается как sum(1), аргумент сохраняется в лексической среде и возвращается новая оболочка function(b).
  • Затем, sum(1)(2)наконец, вызывается function(b)обеспечение 2, и он передает вызов исходной сумме с несколькими аргументами.

4

Если вы понимаете, partialчто вы на полпути. Идея partialсостоит в том, чтобы предварительно применить аргументы к функции и вернуть новую функцию, которая хочет только оставшиеся аргументы. Когда вызывается эта новая функция, она включает в себя предварительно загруженные аргументы вместе с любыми аргументами, которые были ей переданы.

В Clojure +есть функция, но чтобы все было ясно:

(defn add [a b] (+ a b))

Вы можете знать, что incфункция просто добавляет 1 к любому числу, которое она передала.

(inc 7) # => 8

Давайте создадим это сами, используя partial:

(def inc (partial add 1))

Здесь мы возвращаем другую функцию, у которой 1 загружен в первый аргумент add. Так как addпринимает два аргумента, новая incфункция хочет только bаргумент, а не 2 аргумента, как раньше, поскольку 1 уже был применен частично . Таким образом partial, это инструмент для создания новых функций со стандартными значениями. Вот почему в функциональном языке функции часто упорядочивают аргументы от общего к конкретному. Это облегчает повторное использование таких функций для создания других функций.

Теперь представьте, был ли язык достаточно умен, чтобы понять, что для этого addнужны два аргумента. Когда мы передали ему один аргумент вместо того, чтобы прекратить, что если функция частично применила аргумент, мы передали его от нашего имени, понимая, что мы, вероятно, намеревались предоставить другой аргумент позже? Мы могли бы определить incбез явного использования partial.

(def inc (add 1)) #partial is implied

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


3

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

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

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


3

Как и все остальные ответы, карри помогает создавать частично прикладные функции. 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)


3

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

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

Преимущество этого состоит в том, что он может упростить обработку параметров, работая с одним параметром за раз, что также может улучшить гибкость и удобочитаемость программы. Это также делает программу более управляемой. Кроме того, разделение кода на более мелкие части сделает его более удобным для повторного использования.

Например:

function curryMinus(x) 
{
  return function(y) 
  {
    return x - y;
  }
}

var minus5 = curryMinus(1);
minus5(3);
minus5(5);

Я также могу сделать ...

var minus7 = curryMinus(7);
minus7(3);
minus7(5);

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


2

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

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

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

2

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

Например:

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(_:)вам придется создать еще одну лямбду / замыкание, чтобы отправить его в функцию.


это func callbackвозвращение себя? Это называется @ callback(str)итак let callback = callback(str), обратный вызов - это просто возвращаемое значениеfunc callback
nikk wong

нет, func callback(_:data:)принимает два параметра, здесь я даю только один, Stringпоэтому он ожидает следующего ( NSData), поэтому теперь let callbackдругая функция ожидает передачи данных
S2dent

2

Вот пример универсальной и самой короткой версии для функции карри при n нет. парам.

const add = a => b => b ? add(a + b) : a; 

const add = a => b => b ? add(a + b) : a; 
console.log(add(1)(2)(3)(4)());


1

Здесь вы можете найти простое объяснение реализации карри в 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);

1

Карринг является одной из функций высшего порядка в Java Script.

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

Смущенный?

Давайте посмотрим на пример,

function add(a,b)
    {
        return a+b;
    }
add(5,6);

Это похоже на следующую функцию карри,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }
var curryAdd = add(5);
curryAdd(6);

Так что же означает этот код?

Теперь прочитайте определение снова,

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

Все еще в замешательстве? Позвольте мне объяснить в глубине!

Когда вы вызываете эту функцию,

var curryAdd = add(5);

Он вернет вам такую ​​функцию,

curryAdd=function(y){return 5+y;}

Итак, это называется функциями высшего порядка. Это означает, что вызов одной функции по очереди возвращает другую функцию - это точное определение функции высшего порядка. Это самое большое преимущество для легенды, Java Script. Так что возвращайся к карри,

Эта строка передаст второй аргумент функции curryAdd.

curryAdd(6);

что в свою очередь приводит к

curryAdd=function(6){return 5+6;}
// Which results in 11

Надеюсь, вы понимаете использование карри здесь. Итак, перейдя к преимуществам,

Зачем карри?

Это использует возможность повторного использования кода. Меньше кода, меньше ошибок. Вы можете спросить, как меньше кода?

Я могу доказать это с помощью скрипта ECMA 6 новых функций стрелка функции.

Да! ECMA 6, предоставьте нам замечательную функцию под названием функции стрелки,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }

С помощью функции со стрелкой мы можем написать вышеуказанную функцию следующим образом:

x=>y=>x+y

Круто верно?

Итак, меньше кода и меньше ошибок!

С помощью этой функции высшего порядка можно легко разработать код без ошибок.

Я бросаю вам вызов!

Надеюсь, вы поняли, что карри. Пожалуйста, не стесняйтесь комментировать здесь, если вам нужны какие-либо разъяснения.

Спасибо хорошего дня!


0

Есть пример «Карринг в ReasonML».

let run = () => {
    Js.log("Curryed function: ");
    let sum = (x, y) => x + y;
    Printf.printf("sum(2, 3) : %d\n", sum(2, 3));
    let per2 = sum(2);
    Printf.printf("per2(3) : %d\n", per2(3));
  };
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.