V první části Střípky funkcionálního programování a PHP (1) jsem se zabýval hlavně ukázkou funkcí array_map a array_filter. Dneska bych rád oproti minulému příspěvku pokračoval, jak jsem naposledy slíbil a rád bych se zabýval věcmi sousvisejícmi s curryfikací a částečně aplikovanými funkcemi. A taky bych rád ukázal, jak v PHP můžeme vlastně skládat funkce.
Curryfikace a částečně aplikované funkce
Curryfikace a částečně aplikované funkce jsou dalšími vlastnostmi funkcionálního paradigmatu. Nechci se o tom moc rozepisovat, proto jen přednesu základní vysvětlení, co si pod tím představit.
Částečně aplikovaná funkce je taková funkce, jejíž počet zadaných argumentů je menší, než požaduje. Výsledkem částečně aplikované funkce je funkce – právě ta částečně aplikovaná funkce, které de facto jen “čeká”, dokud na ní nebude aplikován zbytek požadovaných argumentů.
Naopak curryfikace je proces, který umožňuje funkci, aby měla schopnost stát se částečně aplikovanou.
Zkusíme si v PHP proto vytvořit funkci, kterou budeme moci částečně aplikovat a ukážeme si její použití na příkladu.
Uvažujme takovou funkci:
<?php
$volume = function ($length = 0, $width = 0, $height = 0) use (&$volume) {
$args = func_get_args();
$numArgs = func_num_args();
if ($numArgs == 3) {
return $length * $width * $height;
}
else if ($numArgs < 3) {
return function() use(&$volume, $args) {
$newArgs = array_merge($args, func_get_args());
return call_user_func_array($volume, $newArgs);
};
}
else {
throw new BadFunctionCallException("Too many arguments");
}
};
$standardVolume = $volume(10);
$vol = $standardVolume(5, 5); // 250
Skládání funkcí
$doubleSum = compose('make_two', 'sum');
$myAdd = compose('add_three', 'make_two', 'add_three', 'sum'); // no mention of arguments in this case
function compose() {
$functions = array_reverse(func_get_args());
return function() use($functions) {
$params = func_get_args();
return array_reduce($functions,
function($result, $next) use ($params) {
return $result === null
? call_user_func_array($next, $params)
: $next($result);
}
);
};
}
http://phpmaster.com/…ing-and-php/
http://blog.lcf.name/…-in-php.html