Skip to content

Instantly share code, notes, and snippets.

@druid628
Created March 4, 2014 21:07
Show Gist options
  • Save druid628/9355652 to your computer and use it in GitHub Desktop.
Save druid628/9355652 to your computer and use it in GitHub Desktop.
<?php
function curry(\Closure $f)
{
$a = [];
$t = 'function($%s) use ($f, $a) { $a[] = $%s; return %s };';
return eval('return '
.array_reduce(
array_reverse((new \ReflectionObject($f))->getMethod('__invoke')->getParameters()),
function($i, $p) use ($t) { return sprintf($t, $p->name, $p->name, $i); },
'call_user_func_array($f, $a);')
);
}
function uncurry(\Closure $f)
{
$getParams = function(\Closure $c) use (&$getParams) {
$m = (new \ReflectionObject($c))->getMethod('__invoke');
if ($m->getNumberOfParameters() === 1
&& $f = $m->invoke($c, null)
and $f instanceof \Closure
) {
return array_merge($m->getParameters(), $getParams($f));
} else {
return $m->getParameters();
}
};
$params = $getParams($f);
return eval(sprintf(
'return function(%s) use ($f) { return $f%s; };',
implode(', ', array_map(function($p) { return '$'.$p->getName(); }, $params)),
array_reduce($params, function($i, $p) { return $i.'->__invoke($'.$p->getName().')'; }, '')
));
}
<?php
$c = curry(function($x, $y) { return $x * $y; });
$u = uncurry($c);
// true
var_dump($c->__invoke(2)->__invoke(4) === $u(2, 4));
<?php
$c = curry(function($w, $x, $y, $z) { return $w + $x + $y + $z; });
$u = uncurry($c);
// true
var_dump($c->__invoke(1)->__invoke(2)->__invoke(3)->__invoke(4) === $u(1, 2, 3, 4));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment