Автор оригинала: FreeCodeCamp Community Member.
Эрик Эллиотт исключительный Сочинение программного обеспечения Серия изначально о том, что заставило меня возбуждено о функциональном программировании. Это обязательно прочитано.
В какой-то момент в серии он упомянул Carrying Отказ И компьютерная наука, и математика согласны с определением:
Carrying включает функции мульти-аргументов в функции unary (единый аргумент).
Функции Curred принимают много аргументов один за раз Отказ Так что если у вас есть
greet = (greeting, first, last) => `${greeting}, ${first} ${last}`; greet('Hello', 'Bruce', 'Wayne'); // Hello, Bruce Wayne
Правильно карри приветствовать
дает тебе
curriedGreet = curry(greet); curriedGreet('Hello')('Bruce')('Wayne'); // Hello, Bruce Wayne
Эта функция 3-аргумента была превращена в три одинарных функция. Когда вы поставляете один параметр, появляется новая функция ожидания следующего.
Должным образом?
Я говорю «правильно карри», потому что некоторые Карри
Функции более гибки в их использовании. Carrying отлично в теории, но вызывая функцию для каждого аргумента устанавливается в JavaScript.
Рамда Карри
Функция позволяет вызывать CurryEgreeT
как это:
// greet requires 3 params: (greeting, first, last) // these all return a function looking for (first, last) curriedGreet('Hello'); curriedGreet('Hello')(); curriedGreet()('Hello')()(); // these all return a function looking for (last) curriedGreet('Hello')('Bruce'); curriedGreet('Hello', 'Bruce'); curriedGreet('Hello')()('Bruce')(); // these return a greeting, since all 3 params were honored curriedGreet('Hello')('Bruce')('Wayne'); curriedGreet('Hello', 'Bruce', 'Wayne'); curriedGreet('Hello', 'Bruce')()()('Wayne');
Обратите внимание, вы можете выбрать несколько аргументов в один выстрел. Эта реализация более полезная во время записи кода.
И как продемонстрировано выше, вы можете вызвать эту функцию навсегда без параметров, и он всегда будет возвращать функцию, которая ожидает оставшихся параметров.
Как это возможно?
Мистер Эллиот поделился Карри
Реализация так же, как Рамда. Вот код, или как он удачно назвал это, волшебное заклинание:
const curry = (f, arr = []) => (...args) => ((a) => (a.length === f.length ? f(...a) : curry(f, a)))([...arr, ...args]);
Ммм …?
Да, я знаю … Это невероятно лаконично, поэтому давайте рефакторием и ценим это вместе.
Эта версия работает то же самое
Я также посыпал Отладчик
заявления для изучения его в инструментах разработчика Chrome.
curry = (originalFunction, initialParams = []) => { debugger; return (...nextParams) => { debugger; const curriedFunction = (params) => { debugger; if (params.length === originalFunction.length) { return originalFunction(...params); } return curry(originalFunction, params); }; return curriedFunction([...initialParams, ...nextParams]); }; };
Откройте свой Инструменты разработчика и следовать!
Давай сделаем это!
Паста приветствовать
и Карри
в вашу консоль. Затем введите CurruedGreeT (приветствие)
и начать безумие.
Пауза на линии 2
Проверяя наши два параметра мы видим Оригиналфункция
это приветствовать
и инициалпарамс
по умолчанию для пустого массива, потому что мы не поставляем его. Перейти к следующей точке останова и ой подожди … Вот и все.
Ага! карри (приветствие)
Просто возвращает новую функцию, которая ожидает еще 3 параметра. Тип CurryEgreeT
в консоли, о том, о чем я говорю.
Когда вы закончите, играя с этим, давайте получим немного безумнее и сделать Сайхелло («Hello»)
Отказ
Пауза на линии 4
Перед движением введите Оригиналфункция
и инициалпарамс
в вашей консоли. Обратите внимание, что мы все еще можем получить доступ к этим 2 параметрам, даже если мы в совершенно новой функции? Это потому, что функции, возвращаемые из родительских функций, наслаждаются объемом их родителей.
Наследство
После того, как родительская функция проходит, они оставляют свои параметры для использования своих детей. Вид как наследство в реальном жизненном смысле.
Карри
был изначально дан Оригиналфункция
и инициалпарамс
а затем вернул функцию «ребенка». Те 2 переменных были не утилизировать Тем не менее, потому что, может быть, этот ребенок нуждается в них. Если он не так, Тогда Этот объем очищается, потому что, когда никто не ссылается на вас, вот когда вы действительно умрете.
ОК, вернемся к линии 4 …
Проверять NextParams
и увидим, что это [«Привет»]
…массив? Но я думал, что мы сказали CurruedGreeT («Hello»)
, не CurruedGreet ([«Hello»)
!
Правильно: мы вызывали CurryEgreeT
с «Привет»
, но благодаря Отдых синтаксис Мы …| повернул «Привет» в
[«Привет»] Отказ
Ты?!
Карри
является общей функцией, которая может поставляться 1, 10 или 10 000 000 параметров, поэтому ему нужен способ ссылки всех них. Использование синтаксиса остальных, как и для того, что захватывает каждый параметр в одном массиве, что делает Карри
работа намного проще.
Давайте перейдем к следующему Отладчик
утверждение.
Строка 6 сейчас, но держись.
Возможно, вы заметили эту строку 12 фактически побежали перед Отладчик
Заявление на линии 6. Если нет, посмотрите ближе. Наша программа определяет функцию под названием CurriedFunction
По линии 5, использует его в строке 12, а Тогда Мы ударили это Отладчик
Заявление о линии 6. А что CurriedFunction
с толку?
[...initialParams, ...nextParams];
Yuuuuup. Смотри на Пармы
на линии 5, и вы увидите [«Привет»]
Отказ Оба инициалпарамс
и NextParams
были массивы, поэтому мы сплющили и объединили их в один массив, используя удобные Распространение оператора Отказ
Вот где происходит хорошие вещи.
Линия 7 говорит: «Если Params
и Оригиналфункция
одинаковы длина, звоните приветствовать
с нами словами, и мы закончили». Что напоминает мне …
Функции JavaScript имеют длину тоже
Вот как Карри
Это магия! Так он решает, следует ли просить больше параметров.
В JavaScript, функция Длина
Собственность говорит вам Сколько аргументов он ожидает Отказ
greet.length; // 3 iTakeOneParam = (a) => {}; iTakeTwoParams = (a, b) => {}; iTakeOneParam.length; // 1 iTakeTwoParams.length; // 2
Если наши предоставленные и ожидаемые параметры совпадают, мы хороши, просто передайте их в оригинальную функцию и закончите работу!
Это баллер?
Но в нашем случае параметры и длина функций являются не тоже самое. Мы только предоставили «Привет»
Итак, params.length
1, а ОригиналFunction.Length
3, потому что приветствовать
ожидает 3 параметра: Приветствие, во-первых, последнее
Отказ
Так что происходит дальше?
Ну, так как Если
Заявление оценивает на ложь
Код будет пропущен к строке 10 и повторно вызовет наш мастер Карри
функция. Это повторно получает приветствовать
И на этот раз, «Привет»
и начинается безумие снова.
Это Рекурсия , мои друзья.
Карри
По сути, является бесконечной петлем самозазывающей, голодных параметрах, которые не будут отдыхать, пока их гость не будет полон. Гостеприимство на самом лучшем.
Назад на линии 2
Те же параметры, что и раньше, кроме инициалпарамс
это [«Привет»]
этот раз. Пропустить еще раз, чтобы выйти из цикла. Введите нашу новую переменную в консоль, Сайхелло
Отказ Это еще одна функция, все еще ожидающая более параметров, но мы становимся теплее …
Давайте возьмем тепло с Сайхеллоотйден («Джон»)
Отказ
Мы снова внутри строки 4, и NextParams
это [«Джон»]
Отказ Перейти к следующему отладчику на линии 6 и проверьте Пармы
: Это [«Привет,« Джон »]
! ?
Почему, почему, почему?
Потому что помните, строка 12 говорит: «Эй, CurredFunction
он дал мне « Привет »
в прошлый раз и « Джон »
на этот раз. Возьми их как в этом массиве [... инициализирует ... NextParams]
. “
Сейчас CurriedFunction
снова сравнивает Длина
из них Пармы
к Оригиналфункция
и с 2 <3
Мы переходим к строке 10 и звоните Карри
снова! И, конечно, мы проходим вместе приветствовать
И наши 2 параметра, ['Привет Джон']
Мы так близко, давайте закончим это и получите полное приветствие!
Sayhellotojohndoe (‘doe’)
Я думаю, что мы знаем, что происходит дальше.
Дел делается
приветствовать
получил его параметры, Карри
Остановившись петли, и мы получили наше приветствие: Здравствуйте, Джон Доу
Отказ
Играйте с этой функцией еще немного. Попробуйте поставить несколько параметров или нет параметров в одном выстрел, получите как можно сумасшедшее. Посмотрите, сколько раз Карри
должен резать, прежде чем вернуть ожидаемый результат.
curriedGreet('Hello', 'John', 'Doe'); curriedGreet('Hello', 'John')('Doe'); curriedGreet()()('Hello')()('John')()()()()('Doe');
Большое спасибо за Эрик Эллиотт Для введения этого мне, и даже больше, спасибо вам за ценить Карри
со мной. До скорого!
Для большего количества контента проверить yazeedb.com !