Що таке "каррінг"?


652

Я бачив посилання на викривлені функції в кількох статтях і блогах, але не можу знайти хорошого пояснення (або принаймні одного, яке має сенс!)


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

3
Тут є хороший підручник для отримання каррі в haskell learnnyouahaskell.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.


235
У практичному розумінні, як я можу змусити використовувати це поняття?
Полуниця

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

62
Я розумію, що робить функція карти, але я не впевнений, чи розумію те, що ви намагаєтесь проілюструвати для мене. Ви хочете сказати, що функція картки представляє поняття currying?
Полуниця

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

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

125

В алгебрі функцій робота з функціями, які беруть кілька аргументів (або еквівалентний один аргумент, який є N-кортежем), є дещо неелегантною - але, як довів Мойсей Шенфінкель (і, незалежно, Haskell Curry), це не потрібно: всі ви потрібні функції, які беруть один аргумент.

Отже, як ви маєте справу з чимось, що ви, природно, висловлюєте як, скажімо f(x,y),? Ну, ви сприймаєте це як еквівалент f(x)(y)- f(x)називайте його g, це функція, і ви застосовуєте цю функцію до y. Іншими словами, у вас є лише функції, які беруть один аргумент, але деякі з цих функцій повертають інші функції (які ТАКОЖ приймають один аргумент ;-).

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


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

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

1
ДОБРЕ. Інші питання тоді. Чи справді таке правдиве твердження? Обчислення лямбда може використовуватися як модель функціонального програмування, проте функціональне програмування не обов'язково застосовується лямбда-числення.
Ерік М

7
Як зазначають сторінки вікіпедії, більшість мов FP "прикрашають" або "збільшують" лямбда-числення (наприклад, з деякими константами та типами даних), а не просто "застосовують" його, але це не так близько. До речі, що створює враження, що, наприклад, Haskell НЕ "обмежує функції лише одним аргументом"? Це, звичайно, так, хоча це не має значення завдяки currying; наприклад div :: Integral a => a -> a -> a- відзначте ці кілька стрілок? "Зображення a для відображення функції a на a" - це одне читання ;-). Ви можете використати (єдиний) аргумент кортежу для div& c, але це було б справді антиідіоматично в Haskell.
Алекс Мартеллі

@ Алекс - Wrt Haskell & arg count, я не витратив багато часу на Haskell, і це було все кілька тижнів тому. Тож було легко зробити помилку.
Eric M

100

Ось конкретний приклад:

Припустимо, у вас є функція, яка обчислює гравітаційну силу, що діє на об'єкт. Якщо ви не знаєте формули, ви можете знайти її тут . Ця функція бере в якості аргументів три необхідні параметри.

Тепер, перебуваючи на землі, ви хочете лише обчислити сили для об'єктів на цій планеті. Функціональною мовою ви можете передати земну масу до функції, а потім частково оцінити її. Те, що ви отримаєте назад, - це ще одна функція, яка бере лише два аргументи і обчислює гравітаційну силу об’єктів на землі. Це називається каррінг.


2
Як цікавість, бібліотека Prototype для JavaScript пропонує функцію "curry", яка робить дуже точно те, що ви тут пояснили: prototypejs.org/api/function/curry
shuckster

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

7
Це звучить як часткове застосування для мене. Я розумію, що якщо застосувати currying, ви можете створити функції з одним аргументом і скласти їх для формування більш складних функцій. Я щось пропускаю?
neontapir

9
@neontapir правильний. Те, що описав Ши, - це не прокляття. Це часткове застосування. Якщо триаргументаційна функція є кривою, і ви називаєте її як f (1), повернення не є функцією з двома аргументами. Ви отримуєте назад функцію з одним аргументом, яка повертає іншу функцію з одним аргументом. Звичену функцію можна будь-коли передавати лише один аргумент. Функція каррі в PrototypeJS також не є currying. Це часткове застосування.
MindJuice

ні (до часткової оцінки) і ні (до витримки). це відомо як часткове застосування. currying потрібен для його включення.
Буде Несс

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.

На закінчення: -

Різниця між застосуванням каррі та частковим застосуванням функції полягає в тому, що: -

Currying приймає функцію і надає нову функцію, що приймає один аргумент, і повертає вказану функцію з її першим аргументом, встановленим на цей аргумент. Це дозволяє нам представляти функції з кількома параметрами у вигляді серії функцій одного аргументу . Приклад: -

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 заданих 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 Я б сказав, навпаки, не гарне пояснення. Я погоджуюсь, що добре пояснити наведений приклад, але люди, як правило, за замовчуванням думають: "Так, цілком зрозуміло, але я міг би зробити те ж саме іншим способом, тож, що корисного є каррі?" Іншими словами, я б хотів, щоб у нього було достатньо контексту чи пояснень, щоб висвітлити не лише те, як працює каррінг, але й чому це не марне і тривіальне спостереження порівняно з іншими способами додавання десяти.
Уїтніленд

29

Викрита функція - це функція з декількох аргументів, переписаних таким чином, що вона приймає перший аргумент і повертає функцію, яка приймає другий аргумент тощо. Це дозволяє функціям декількох аргументів частково застосувати деякі свої початкові аргументи.


5
"Це дозволяє функціям декількох аргументів частково застосувати деякі свої початкові аргументи." - чому це корисно?
акарлон

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

1
Дякую, це має сенс. Я трохи більше читав, і він став на місце.
акарлон

4
Я думаю, що ця відповідь відповідає правильному в стислій формі. "Випробування" - це процес прийняття функції з декількох аргументів і перетворення її в серйозну з функцій, за якими кожен приймає один аргумент і повертає функцію одного аргументу, або у випадку остаточної функції повертає фактичний результат . Це може бути зроблено автоматично для вас мовою, або ви можете зателефонувати на функцію curry () на інших мовах, щоб створити версію curried. Зауважте, що викликати функцію curried із параметром - це не 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 ("currying", "Як завжди, wikipedia має хороший підсумок. .. ") Отже, у вас є функція з двома аргами. Здавалося б, що каррінг повинен дати вам три різні функції, які ви б склали?
Ерік М

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

(btw - ">>>" - це запит в інтерактивному інтерпретаторі Python, не входить до коду.)
Anon,

ОК, дякую за роз’яснення щодо аргументів. Я знаю про підказку інтерпретатора Python, я намагався процитувати рядки, але це не вийшло ;-)
Eric M

Після Вашого коментаря я шукав та знайшов інші посилання, зокрема тут на SO, на різницю між "currying" та ". "часткове застосування" у відповідь на безліч випадків неточного використання, з яким я знайомий. Дивіться, наприклад: stackoverflow.com/questions/218025/…
Анон

5

Currying - це переклад функції з callable як f(a, b, c)в callable як f(a)(b)(c).

Інакше currying - це коли ви розбиваєте функцію, яка бере кілька аргументів на ряд функцій, які беруть частину аргументів.

Буквально каррінг - це перетворення функцій: з одного способу виклику в інший. У JavaScript ми зазвичай робимо обгортку, щоб зберегти початкову функцію.

Заготівля не викликає функції. Це просто перетворює.

Давайте зробимо функцію curry, яка виконує curry для двоаргументних функцій. Іншими словами, 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/currying-and-partial-function-application.aspx

Як згадували інші, це лише спосіб мати функцію одного параметра.

Це корисно тим, що вам не потрібно вважати, скільки параметрів буде передано, тому вам не потрібні 2 параметри, 3 параметри та 4 параметри функції.


3

Як і всі інші відповіді, currying допомагає створити частково застосовані функції. Javascript не забезпечує вбудовану підтримку автоматичного висихання. Отже, наведені вище приклади можуть не допомогти в практичному кодуванні. У живописі (який по суті складається з js) є чудовий приклад http://livescript.net/

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

У наведеному вище прикладі, коли ви надали менше аргументів, сценарій виконання сценарію створює для вас нову функцію (подвійний)


3

Каррі може спростити ваш код. Це одна з головних причин використовувати це. Currying - це процес перетворення функції, яка приймає n аргументів у n функцій, які приймають лише один аргумент.

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

Перевага цього полягає в тому, що воно може спростити обробку параметрів, обробляючи один параметр одночасно, що також може підвищити гнучкість і читабельність програми. Це також робить програму більш керованою. Також поділ коду на більш дрібні шматочки зробить його зручним для повторного використання.

Наприклад:

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

Прикладом currying може бути, коли функцій ви знаєте лише один з параметрів на даний момент:

Наприклад:

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:)приймає два параметри, тут я даю лише один, the String, тому він чекає наступного ( NSData), ось чому зараз let callbackє ще одна функція, яка чекає передачі даних
S2dent

2

Ось приклад загальної та найкоротшої версії для функціонування currying з n no. парам.

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

Тут ви можете знайти просте пояснення реалізації currying у 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.

Currying - це функція багатьох аргументів, яка переписана таким чином, що вона бере перший аргумент і повертає функцію, яка в свою чергу використовує решта аргументів і повертає значення.

Плутати?

Давайте подивимось приклад,

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

То що означає цей код?

Тепер знову прочитайте визначення,

Currying - це функція багатьох аргументів, яка переписується таким чином, що вона бере перший аргумент і повертає функцію, яка в свою чергу використовує решта аргументів і повертає значення.

Все-таки плутати? Дозвольте пояснити глибоко!

Коли ви викликаєте цю функцію,

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

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

Чому каррінг?

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

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

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

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

За допомогою функції стрілки ми можемо записати описану вище функцію так,

x=>y=>x+y

Класно, правда?

Отже, менше коду та менше помилок !!

За допомогою цих функцій вищого порядку можна легко розробити код без помилок.

Я кидаю виклик тобі!

Сподіваюся, ви зрозуміли, що таке каррі. Будь ласка, не соромтесь коментувати тут, якщо вам потрібні якісь пояснення.

Спасибі, приємного дня!


0

Є приклад "Currying in 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.