Currying
Rozwijanie funkcji (ang. currying) – operacja w funkcyjnych językach programowania polegająca na przekształceniu funkcji, która pobiera parę argumentów i zwraca wynik w funkcję, która po pobraniu argumentu zwraca funkcję, która pobiera argument i zwraca wynik [1]. Operacja odwrotna nosi nazwę zwijanie funkcji (ang. uncurrying)[2].
Podstawą dla tej operacji jest ugruntowanie systemu typów w językach funkcyjnych na rachunku lambda z typami. Taki rachunek na mocy izomorfizmu Curry’ego-Howarda jest równoważny pewnej logice intuicjonistycznej, a zatem operacja ta odpowiada tautologii logiki intuicjonistycznej:
Oryginalna nazwa została zaproponowana przez Christophera Stracheya w 1967 roku, jako nawiązanie do nazwiska logika Haskella Curry’ego.
Zastosowanie w programowaniu
W przypadku języków programowania stosuje się rozszerzenie tego mechanizmu. Najbardziej uniwersalnym jest taki, który zwraca funkcję, która przyjmuje argumenty i zwraca funkcje dopóki suma argumentów jest mniejsza niż liczba parametrów początkowej funkcji. Natomiast gdy ich liczba przekroczy sumę parametrów, wywoływana jest pierwotna funkcja.
Przykład JavaScript
// ES5
function curry(fn) {
var init_args = [].slice.call(arguments, 1);
var len = fn.length;
return function() {
var args = init_args.slice();
function call() {
args = args.concat([].slice.call(arguments));
if (args.length >= len) {
return fn.apply(null, args);
} else {
return call;
}
};
return call.apply(null, arguments);
};
}
// ES6
function curry(fn, ...init_args) {
var len = fn.length;
return function() {
var args = init_args.slice();
function call(...fn_args) {
args = args.concat(fn_args);
if (args.length >= len) {
return fn.apply(null, args);
} else {
return call;
}
};
return call.apply(null, arguments);
};
}
function add(a,b,c) {
return a+b+c;
}
var curry_add = curry(add);
console.log(curry_add(2,3,4)); // 9
console.log(curry_add(2)(3)(4)); // 9
console.log(curry_add(2,3)(4)); // 9
Przypisy
- ↑ Simpson 2020 ↓, s. 59–63.
- ↑ Simpson 2020 ↓, s. 68.
Bibliografia
- Kyle Simpson: JavaScript funkcyjnie. Wydawnictwo Naukowe PWN, 2020. ISBN 83-01-21196-2.