HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>Каррирование - очень интересная техника, позволяющая сильно упростить использование частичного применения на практике. Многие путают эти понятия, но, как вы увидите далее, они обозначают совершенно разные вещи.</p>
1 <p>Каррирование - очень интересная техника, позволяющая сильно упростить использование частичного применения на практике. Многие путают эти понятия, но, как вы увидите далее, они обозначают совершенно разные вещи.</p>
2 <p>В предыдущем уроке нам приходилось писать функцию-обертку для применения.</p>
2 <p>В предыдущем уроке нам приходилось писать функцию-обертку для применения.</p>
3 <p>Eсли бы наша функция getAverageSalary была каррирована, то все было бы значительно проще. Каррирование - это процесс превращения функции от n аргументов в цепочку вложенных n-функций от одного аргумента. Соответственно, каррированная функция - это множество функций от одного аргумента.</p>
3 <p>Eсли бы наша функция getAverageSalary была каррирована, то все было бы значительно проще. Каррирование - это процесс превращения функции от n аргументов в цепочку вложенных n-функций от одного аргумента. Соответственно, каррированная функция - это множество функций от одного аргумента.</p>
4 <p>Предположим, что у нас есть функция const sum = (a, b, c) =&gt; a + b + c, которая складывает три числа. Тогда ее каррированная версия будет выглядеть так: const sum2 = a =&gt; b =&gt; c =&gt; a + b + c, а использование таким: sum2(5)(10)(-2). То же самое, разложенное по функциям:</p>
4 <p>Предположим, что у нас есть функция const sum = (a, b, c) =&gt; a + b + c, которая складывает три числа. Тогда ее каррированная версия будет выглядеть так: const sum2 = a =&gt; b =&gt; c =&gt; a + b + c, а использование таким: sum2(5)(10)(-2). То же самое, разложенное по функциям:</p>
5 <p>Посмотрите внимательно на определение a =&gt; b =&gt; c =&gt; a + b + c. Эта запись очень краткая и одновременно очень емкая. Суммарное количество функций считается очень легко, оно равно сумме всех стрелок =&gt;. Для лучшего понимания можно добавить скобки a =&gt; (b =&gt; (c =&gt; a + b + c)). Для каждого определения функции все, что находится справа от стрелки, является ее телом, каким бы сложным оно ни было. Поначалу такая запись может помочь понять, как друг в друга вложены функции, но со временем, когда вы привыкнете к обычной записи, она будет больше мешать.</p>
5 <p>Посмотрите внимательно на определение a =&gt; b =&gt; c =&gt; a + b + c. Эта запись очень краткая и одновременно очень емкая. Суммарное количество функций считается очень легко, оно равно сумме всех стрелок =&gt;. Для лучшего понимания можно добавить скобки a =&gt; (b =&gt; (c =&gt; a + b + c)). Для каждого определения функции все, что находится справа от стрелки, является ее телом, каким бы сложным оно ни было. Поначалу такая запись может помочь понять, как друг в друга вложены функции, но со временем, когда вы привыкнете к обычной записи, она будет больше мешать.</p>
6 <p>С другой стороны, если нам нужно каррировать существующую функцию без ее реализации, то делается это так: const sum2 = a =&gt; b =&gt; c =&gt; originalSum(a, b, c). То есть создается цепочка вложенных функций, в которой количество вложений равно количеству аргументов исходной функции и в конце которой происходит вызов оригинальной функции.</p>
6 <p>С другой стороны, если нам нужно каррировать существующую функцию без ее реализации, то делается это так: const sum2 = a =&gt; b =&gt; c =&gt; originalSum(a, b, c). То есть создается цепочка вложенных функций, в которой количество вложений равно количеству аргументов исходной функции и в конце которой происходит вызов оригинальной функции.</p>
7 <p>Разберем происходящее по шагам.</p>
7 <p>Разберем происходящее по шагам.</p>
8 <p>То же самое происходит и при таком вызове: sum(10)(3)(0), разница только в том, что вызовы происходят без создания промежуточных констант.</p>
8 <p>То же самое происходит и при таком вызове: sum(10)(3)(0), разница только в том, что вызовы происходят без создания промежуточных констант.</p>
9 <p>И задача для самоконтроля. Сколько раз нужно вызвать цепочку функций const greeting = () =&gt; () =&gt; () =&gt; () =&gt; console.log('Hey!'), чтобы дойти до конца? Обязательно попробуйте прямо сейчас выполнить это задание.</p>
9 <p>И задача для самоконтроля. Сколько раз нужно вызвать цепочку функций const greeting = () =&gt; () =&gt; () =&gt; () =&gt; console.log('Hey!'), чтобы дойти до конца? Обязательно попробуйте прямо сейчас выполнить это задание.</p>
10 <p>Теперь вернемся к нашей функции расчета зарплаты в ее каррированном виде. Представим, что теперь у нас в распоряжении две вложенных функции от одного аргумента: const getAverageSalary = job =&gt; country =&gt; /* body */:</p>
10 <p>Теперь вернемся к нашей функции расчета зарплаты в ее каррированном виде. Представим, что теперь у нас в распоряжении две вложенных функции от одного аргумента: const getAverageSalary = job =&gt; country =&gt; /* body */:</p>
11 <p>Попробуем частично применить:</p>
11 <p>Попробуем частично применить:</p>
12 <h2>Применение в реальной жизни</h2>
12 <h2>Применение в реальной жизни</h2>
13 <p>В функциональных языках, подобных haskell, вопросов об использовании каррированных функций просто не встает. Они там используются постоянно, начиная с самых азов. Это одна из причин, почему стоит учить подобные языки, даже если вы не будете писать на них программы. В императивных языках такое происходит значительно реже, но не в JS. JS по своей сути очень близок к функциональным языкам. Изначально он должен был быть написан на Scheme, языке из семейства Lisp, и функции в нем занимают центральное место. Каррирование используется в различных библиотеках и иногда является их ключевой "фичей", как, например, здесь:<a>https://github.com/substantial/updeep</a>.</p>
13 <p>В функциональных языках, подобных haskell, вопросов об использовании каррированных функций просто не встает. Они там используются постоянно, начиная с самых азов. Это одна из причин, почему стоит учить подобные языки, даже если вы не будете писать на них программы. В императивных языках такое происходит значительно реже, но не в JS. JS по своей сути очень близок к функциональным языкам. Изначально он должен был быть написан на Scheme, языке из семейства Lisp, и функции в нем занимают центральное место. Каррирование используется в различных библиотеках и иногда является их ключевой "фичей", как, например, здесь:<a>https://github.com/substantial/updeep</a>.</p>