share apply dispatch with compiled fixed functions
This commit is contained in:
parent
bdb49b0d78
commit
66705f3e31
@ -11,10 +11,10 @@ namespace Kadet\Functional\Utils;
|
||||
|
||||
|
||||
use function Kadet\Functional\apply;
|
||||
use function Kadet\Functional\applyWithArity;
|
||||
use Kadet\Functional\Compilable;
|
||||
use function Kadet\Functional\compile;
|
||||
use Kadet\Functional\Decorator;
|
||||
use function Kadet\Functional\partial;
|
||||
use function Kadet\Functional\reflect;
|
||||
|
||||
class FixedFunction implements Decorator, Compilable
|
||||
@ -70,22 +70,7 @@ class FixedFunction implements Decorator, Compilable
|
||||
$call = $fixed instanceof CurriedFunction ? $fixed : compile($fixed);
|
||||
|
||||
$self = static function (...$args) use (&$self, $fixed, $call, $variadic, $required, $all) {
|
||||
array_unshift($args, $self);
|
||||
|
||||
switch (true) {
|
||||
case $variadic:
|
||||
return partial($fixed, ...$args);
|
||||
|
||||
case count($args) >= $all:
|
||||
$applied = $call(...array_slice($args, 0, $all));
|
||||
return is_callable($applied) ? apply($applied, ...array_slice($args, $all)) : $applied;
|
||||
|
||||
case count($args) >= $required:
|
||||
return $call(...$args);
|
||||
|
||||
default:
|
||||
return partial($fixed, ...$args);
|
||||
}
|
||||
return applyWithArity($fixed, $call, $variadic, $required, $all, [$self, ...$args]);
|
||||
};
|
||||
|
||||
return $self;
|
||||
|
||||
@ -24,29 +24,45 @@ function apply(callable $callable, ...$args)
|
||||
{
|
||||
try {
|
||||
$reflection = reflect($callable);
|
||||
$required = $reflection->getNumberOfRequiredParameters();
|
||||
$all = $reflection->getNumberOfParameters();
|
||||
|
||||
switch (true) {
|
||||
case $reflection->isVariadic():
|
||||
return partial($callable, ...$args);
|
||||
|
||||
case count($args) >= $all:
|
||||
$applied = $callable(...array_slice($args, 0, $all));
|
||||
return is_callable($applied) ? apply($applied, ...array_slice($args, $all)) : $applied;
|
||||
|
||||
case count($args) >= $required:
|
||||
return $callable(...$args);
|
||||
|
||||
default:
|
||||
return partial($callable, ...$args);
|
||||
}
|
||||
return applyWithArity(
|
||||
$callable,
|
||||
$callable,
|
||||
$reflection->isVariadic(),
|
||||
$reflection->getNumberOfRequiredParameters(),
|
||||
$reflection->getNumberOfParameters(),
|
||||
$args
|
||||
);
|
||||
} catch (\ReflectionException $exception) {
|
||||
// if cannot gather necessary information for intelligent application just use normal one
|
||||
return $callable(...$args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The argument dispatch of apply(), with the arity of $callable already known: it calls $call when there are enough
|
||||
* arguments and partially applies $callable otherwise.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
function applyWithArity(callable $callable, callable $call, bool $variadic, int $required, int $all, array $args)
|
||||
{
|
||||
switch (true) {
|
||||
case $variadic:
|
||||
return partial($callable, ...$args);
|
||||
|
||||
case count($args) >= $all:
|
||||
$applied = $call(...array_slice($args, 0, $all));
|
||||
return is_callable($applied) ? apply($applied, ...array_slice($args, $all)) : $applied;
|
||||
|
||||
case count($args) >= $required:
|
||||
return $call(...$args);
|
||||
|
||||
default:
|
||||
return partial($callable, ...$args);
|
||||
}
|
||||
}
|
||||
|
||||
function curry(callable $callable, ?int $threshold = null, ...$args): CurriedFunction
|
||||
{
|
||||
return new CurriedFunction($callable, $threshold, ...$args);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user