За последний месяц я уловил и забыл тонкости функций каррирования несколько раз, так что вот небольшая статья, в которой будет рассмотрена эта концепция в целом.
Прежде чем мы углубимся в это, знайте, что каррирование часто используется в функциональном программировании и основано на концепции функций более высокого порядка , то есть передачи одной функции другой. Если это звучит сбивающе с толку, ознакомьтесь с кратким руководством по этой концепции, которое я написал здесь . Это 3-х минутное чтение, чтобы вы быстро освоились.
Хотя функция каррирования получила свое название от Haskell Curry, это помогло мне думать об этом, как о создании карри. Традиционно, когда вы вызываете функцию, вы передаете сразу все ее аргументы и то, что функция возвращает ваш результат. Когда вы каррируете функцию, она разделяется на частичные функции и принимает свои аргументы по одному , передавая первый аргумент первой частичной функции. Когда возвращается первая часть, каррированная функция принимает следующий аргумент и так далее, пока не останется больше аргументов для обработки. Добавьте аргумент и дайте ему закипеть. Когда он будет готов, добавьте следующий аргумент. Это очень похоже на приготовление карри.
Ладно, там много чего нужно распаковывать. Не паникуйте . Это простая концепция, и через несколько минут вы тоже с ней научитесь. Ознакомьтесь с примерами кодирования ниже.
Итак, давайте посмотрим на эту традиционно написанную функцию madlibs ниже.
let madlibs = (name, food, number) =>
'My name is ' + name +
' and I love ' + food +
', I could eat ' + number +' plates of it!'
console.log (madlibs("Jerry","Spaghetti","10"))
My name is Jerry and I love Spaghetti, I could eat 10 plates of it!
let madlibs =
name =>
food =>
number =>
'My name is ' + name +
' and I love ' + food +
', I could eat ' + number +' plates of it!'
console.log (madlibs("Jerry")("Spaghetti")("10"))
My name is Jerry and I love Spaghetti, I could eat 10 plates of it!
console.log (madlibs("Jerry")("Spaghetti"))
(number) => 'My name is ' + name + ' and I love ' + food + ', I could eat ' + number + ' plates of it!'
Здесь важно отметить, как каррирование дает нам возможность медленно добавлять аргументы в нашу функцию. Хотя может быть не совсем очевидно, почему именно сейчас, но тот факт, что мы можем передавать аргументы постепенно и возвращаться к нашей функции позже с дополнительными аргументами, полезен, мы вскоре вернемся к этой концепции.
Но прежде чем мы это сделаем, вам нужно знать еще одну вещь: мы можем использовать несколько библиотек функционального программирования, чтобы JavaScript каррировал традиционную для нас функцию, например lodash:
import _ from 'lodash'
let madlibs = (name, food, number) =>
'My name is ' + name +
' and I love ' + food +
', I could eat ' + number +' plates of it!'
madlibs = _.curry(madlibs)
let jerry = madlibs("Jerry")
let jerrysFavoriteFood = jerry("Spaghetti")
console.log (jerrysFavoriteFood('10'))
let jerry = madlibs("Jerry")
My name is Jerry and I love Spaghetti, I could eat 10 plates of it!
let users = [
{id: 1, username: "cambot", favorite_color: "red"},
{id: 2, username: "gypsy", favorite_color: "purple"},
{id: 3, username: "tom", favorite_color: "red"},
{id: 4, username: "crow", favorite_color: "gold"},
{id: 5, username: "joel", favorite_color: "red"},
{id: 6, username: "mike", favorite_color: "blue"},
{id: 7, username: "jonah", favorite_color: "yellow"}
]
let faveColor = (favorite_color, obj) => obj.favorite_color === favorite_color
let usersThatLoveRed = users.filter(x => faveColor('red', x))
console.log(usersThatLoveRed)
[
{id:1,username:"cambot",favorite_color:"red"},{id:3,username:"tom",favorite_color:"red"},{id:5,username:"joel",favorite_color:"red"}
]
Это работает, но посмотрите, как мы звоним faveColor. Мы передаем ему 2 аргумента 'red’и x. Используя каррирование, мы можем сделать код более читабельным. В приведенном ниже примере мы достигли того же результата:
import _ from 'lodash'
let users = [
{id: 1, username: "cambot", favorite_color: "red"},
{id: 2, username: "gypsy", favorite_color: "purple"},
{id: 3, username: "tom", favorite_color: "red"},
{id: 4, username: "crow", favorite_color: "gold"},
{id: 5, username: "joel", favorite_color: "red"},
{id: 6, username: "mike", favorite_color: "blue"},
{id: 7, username: "jonah", favorite_color: "yellow"}
]
let faveColor = _.curry((favorite_color, obj) => obj.favorite_color === favorite_color)
let usersThatLoveRed = users.filter(faveColor('red'))
console.log(usersThatLoveRed)
И действительно, в этом и суть функций каррирования.
lodash, мы берем функцию, которая принимает несколько аргументов, и разделяем ее на частичные функции, которые принимают отдельные аргументы.
На этой неделе я получил электронное письмо от участника ежедневного списка рассылки. Они хотели знать: какие ресурсы вы посещаете ежедневно, еженедельно и ежемесячно? Отличный вопрос! Я рад поделиться некоторыми мыслями о моем рабочем процессе и основных ресурсах, которые я использую.
Цель этой серии блогов — углубиться в библиотеку Lit и получить всестороннее представление о ее уникальных функциях и о том, чем она отличается от других библиотек и фреймворков на рынке. Серия разделена на три части, охватывающие такие темы, как 1.
Мы часто обнаруживаем, что изо всех сил пытаемся реализовать то, что, как мы знаем, полезно для нас. От того, чтобы сказать значимому другому, что мы любим его, до того, чтобы помнить, что нужно говорить как пират, всегда будут те, кто утверждает, что день, неделя или месяц событий не нужны, потому что они уже делают эти вещи.
Зуд в моей руке распространился, когда я торговалась с местным книгопродавцом за еще одну книгу. Эта книга, как и остальные, которые я купил недавно, займет свое место в моей стопке «Для чтения» (TBR); и тем не менее, я купил его.
Сколько раз вы, не задумываясь, выбрасывали пластиковую бутылку, стеклянную банку, алюминиевую банку или пакет экологически чистой энергии? Сколько раз вы хотели получить что-то взамен за их переработку? Если вы похожи на большинство людей, ответ, вероятно, много раз. Переработка часто рассматривается как хлопотное дело, рутинная работа или обязанность, не приносящая немедленных или ощутимых выгод.
Вы можете быть исследователем OSINT, игроком CTF или просто тем, кто получает спам-звонки. Кто-то, кто пытается проверить номер, который вы видели в рекламе.