JavaScript에서 커링 currying 함수 작성하기를 다시 보다가 PHP로도 작성해봤다.

function curry($fn) {
    $arity = (new ReflectionFunction($fn))->getNumberOfParameters();

    return ($resolver = function (...$memory) use ($fn, $arity, &$resolver) {
        return function (...$args) use ($fn, $arity, $resolver, $memory) {
            $local = array_merge($memory, $args);
            $next = count($local) >= $arity ? $fn : $resolver;
            return $next(...$local);
        };
    })();
}

js 버전도 요즘 스타일로 작성하면 좀 더 간결할 것 같다. php와 js와의 차이점을 적어보면,

아래는 함수 작성하면서 사용한 테스트다.

$nullary = curry(function() { return 1; });
assert($nullary() === 1, 'nullary failed');

$unary = curry(function($a) { return $a; });
assert($unary(2) === 2, 'unary with one param failed');

$binary = curry(function($a, $b) { return $a + $b; });
assert($binary(2)(10) === 12, 'binary, one and one param failed case 1');
assert($binary(2)(20) === 22, 'binary, one and one param failed case 2');
assert($binary(2, 20) === 22, 'binary, two param failed');

$ternary = curry(function($a, $b, $c) { return $a + $b + $c; });
assert($ternary(2)(10)(4) === 16, 'ternary, one and one and one param failed');
assert($ternary(2, 20)(2) === 24, 'ternary, two and one param failed');
assert($ternary(4)(2, 20) === 26, 'ternary, one and two param failed case 1');
assert($ternary(4)(4, 20) === 28, 'ternary, one and two param failed case 2');
assert($ternary(4, 4, 20) === 28, 'ternary, three param failed');

function ternary($a, $b, $c) {
    return $a + $b + $c;
}

$namedTernary = curry('ternary');
assert($namedTernary(2)(10)(4) === 16, 'named ternary, one and one and one param failed');
assert($namedTernary(2, 20)(2) === 24, 'named ternary, two and one param failed');
assert($namedTernary(4)(2, 20) === 26, 'named ternary, one and two param failed case 1');
assert($namedTernary(4)(4, 20) === 28, 'named ternary, one and two param failed case 2');
assert($namedTernary(4, 4, 20) === 28, 'named ternary, three param failed');

웹사이트 설정

웹페이지 색상을 선택하세요