|
|
|||||||||||||||||||||||||||||
|
Eще раз о каррировании и частичном применении в PHPИсточник: habrahabr Bodigrim
В недавней статье предложена реализация каррирования (currying) и частичного применения (partial function application) на PHP. Ее фундаментальным недостатком является то, что результатом каррирования является не функция, а объект. Он уже не может быть передан в качестве callback-параметра, а для подстановки аргументов приходится использовать специальный синтаксис. В настоящем тексте предлагается новая, прозрачная реализация этих конструкций для PHP 5.3 и выше. Краткий ликбезКаррирование и частичное применение используются для построения фабрик функций. Эта техника особенно полезна, если надо породить функцию с заданным интерфейсом для передачи в другую функцию как аргумента для выполнения пользовательской фильтрации, сортировки, преобразования и т. п. Пусть у нас есть некая функция с множеством параметров и мы хотим массово строить функции, совпадающих с данной при фиксации тех или иных аргументов. Например, пусть у нас есть "черный ящик" - функция solve(f, x0, ε), находящая решение уравнения f(x) = 0 в окрестности начальной точки x0 с точностью ε. Тогда при помощи вызова частичного применения мы можем построить функцию solve1(x0, ε) ≡ solve(x − tg x, x0, ε). Или даже функцию solve2(ε), которая решала бы некое фиксированное уравнение в окрестности фиксированной начальной точки с переменной точностью. Разумеется, в каждом частном случае мы можем написать функцию-обертку типа
однако было бы удобнее иметь универсальный механизм, которым и является частичное применение. Каррирование - это процедура, преобразующая функцию от n переменных в цепочку из n функций одной переменной, выполняя поочередную подстановку аргументов. Например, пусть add(a, b) = a + b, a curry_add - результат каррирования функции add. Тогда вызов curry_add(a) для каждого a будет порождать функции одного аргумента, прибавляющие к нему a, т. е. curry_add(a)(b) = add(a, b). Больше примеров будет приведено ниже. Детальнее с каррированием и частичным применением можно ознакомиться в большой статье Е. Кирпичева "Элементы функциональных языков" (раздел 5). Каррирующая функцияИтак, слайды. Все, что нам нужно, - это следующий код, который заменяет исходную функцию ее каррированной версией.
Классический примерПусть у нас определена функция add.
Мы можем построить ее каррированную версию.
Проверим, что полученная функция ведет себя так же, как и исходная.
Теперь подставим только первый аргумент, чтобы сгенерировать функции инкремента и декремента.
Еще примерыМы можем совершенно прозрачно подставлять произвольное количество начальных аргументов и получать полноценную функцию, в которую можно снова подставить не все аргументы. Например,
Результат каррирования можно без проблем передать в качестве callback-параметра другой функции. Например, пусть нам надо вычислить массы кубов по плотности и массиву длин сторон. Мы можем сделать это следующим образом.
Примечания
Ссылки по теме
|
|