function with_list($f) { $arity = arity($f); return function () use($f, $arity) { $args = func_get_args(); if ($arity > 0 && count($args) != $arity - 1) { throw new BadFunctionCallException('Oops'); } return function ($xs) use($f, $args) { return $f($args[0], $args[1], $xs); }; }; }
$n = mt_rand(2, 50); return uncurry(nary(function () { return sum(func_get_args()); }, $n), range(1, $n)) !== sum(range(1, $n)); }, 'arity1' => function () { return arity(function ($a, $b) { }) !== 2; }, 'arity2' => function ($n) { return arity(nary(function () { }, $n % 100)) !== $n % 100; }, 'arity3' => function () { return arity('plus') !== 2; }, 'arity4' => function () { return arity(plus(2)) !== 1; }, 'arity5' => function () { return arity(flip('plus')) !== 2; }, 'key_map' => function () { return key_map('plus', [1 => 2, 4 => 8, 16 => 32]) !== [1 => 3, 4 => 12, 16 => 48]; }, 'flip1' => function () { return flip(array_(2), 1, 2) !== [2, 1]; }, 'flip2' => function () { return flip('map', [-1, -2], plus(5)) !== [4, 3]; }, 'compose1' => function ($x, $y, $z) { return call(compose(plus($x), mult($y)), $z) !== $x + $y * $z; }, 'compose2' => function ($x, $y, $z) { return call(compose(mult($x), plus($y)), $z) !== $x * ($y + $z); }, 'compose3' => function ($x, $y, $z) { $f = flip('map', [$x, $y]); $c = compose($f, 'plus'); return $c($z) !== [$x + $z, $y + $z]; }, 'compose4' => function ($n) {
function inject($iterable, $memo, $lambda) { if (arity($lambda) < 3) { foreach ($iterable as $v) { $memo = $lambda($memo, $v); } } else { foreach ($iterable as $k => $v) { $memo = $lambda($memo, $k, $v); } } return $memo; }
}, 'gt' => function ($x, $y) { return $x > $y; }, 'lte' => function ($x, $y) { return $x <= $y; }, 'gte' => function ($x, $y) { return $x >= $y; }, 'instance' => function ($x, $y) { return $x instanceof $y; }, 'power' => nary('pow', 2), 'apply' => nary('call_user_func'), 'array_' => nary('func_get_args'), 'discard_keys' => function ($arr) { return array_combine($arr, $arr); }, 'map' => nary('array_map', 2), 'map_keys' => function ($f, $a) { return array_combine(map($f, keys($a)), $a); }, 'flip' => function ($f) { return nary(function ($x, $y) use($f) { return $f($y, $x); }, arity($f)); }]); defuns(['with' => flip(apply(2)), 'over' => flip('map')]); function compose($a, $b) { $funcs = array_reverse(func_get_args()); $f = op(array_shift($funcs)); return function ($x) use($funcs, $f) { static $curried = true; return array_reduce($funcs, function ($x, $f) { return call_user_func(op($f), $x); }, call_user_func_array($f, func_get_args())); }; } defun('implode_', 'implode'); defun('join_', implode_(''));
function test($test) { return call_user_func_array($test, array_map('random', up_to(arity($test)))); }
<?php set_error_handler(function () { var_dump(array('args' => func_get_args(), 'trace' => debug_backtrace())); die; }); defun('sample', function ($f, $n) { return array_map($f, up_to($n)); }); defuns(call_user_func(function () { $tests = array(); $run = function ($t) { return call_user_func_array($t[0], sample('random', $t[1])); }; return array('deftest' => function ($name, $test) use(&$tests) { $tests[$name] = array($test, arity($test)); }, 'runtests' => function ($t) use(&$tests, $run) { return is_array($t) ? $run($t) : array_filter(array_map($run, $tests)); }, 'deftests' => key_map('deftest')); }));