Střípky funkcionálního programování a PHP (2)

4. 8. 2013 | #php

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

Diskuse

comments powered by Disqus

Tento web používá k poskytování služeb, personalizaci reklam a analýze návštěvnosti soubory cookie. Používáním tohoto webu s tím souhlasíte. Další informace