specialize compiled partials with one placeholder
This commit is contained in:
parent
04dfb21916
commit
db3aab644e
@ -82,6 +82,24 @@ class PartiallyAppliedFunction implements Decorator, Compilable
|
|||||||
return static fn (...$args) => $callable(...$arguments, ...array_slice(array_values($args), 0, $extra));
|
return static fn (...$args) => $callable(...$arguments, ...array_slice(array_values($args), 0, $extra));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The common shape, e.g. partial(str_pad(...), _, 8): one placeholder and no room for more arguments. An
|
||||||
|
// unfilled placeholder stays in place, as below.
|
||||||
|
if (count($placeholders) === 1 && $extra === 0) {
|
||||||
|
$position = $placeholders[0];
|
||||||
|
|
||||||
|
if ($position === 0) {
|
||||||
|
$rest = array_slice($arguments, 1);
|
||||||
|
|
||||||
|
return static fn ($value = PLACEHOLDER) => $callable($value, ...$rest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return static function ($value = PLACEHOLDER) use ($callable, $arguments, $position) {
|
||||||
|
$arguments[$position] = $value;
|
||||||
|
|
||||||
|
return $callable(...$arguments);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return static function (...$args) use ($callable, $arguments, $placeholders, $extra) {
|
return static function (...$args) use ($callable, $arguments, $placeholders, $extra) {
|
||||||
$args = array_values($args);
|
$args = array_values($args);
|
||||||
$count = min(count($placeholders), count($args));
|
$count = min(count($placeholders), count($args));
|
||||||
|
|||||||
@ -107,6 +107,17 @@ class CompileTest extends \PHPUnit\Framework\TestCase
|
|||||||
$this->assertSame('aa', f\compile(f\curry(str_repeat(...), null, 'a'))(2, 'extra'));
|
$this->assertSame('aa', f\compile(f\curry(str_repeat(...), null, 'a'))(2, 'extra'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCompileSinglePlaceholderOfInternalTarget()
|
||||||
|
{
|
||||||
|
$leading = f\partial(str_pad(...), _, 3, '0', STR_PAD_LEFT);
|
||||||
|
$middle = f\partial(substr(...), 'abcdef', _, 2);
|
||||||
|
|
||||||
|
$this->assertSame('007', f\compile($leading)('7', 'extra'));
|
||||||
|
$this->assertSame('cd', f\compile($middle)(2, 'extra'));
|
||||||
|
$this->assertSame($this->outcome(fn () => $leading()), $this->outcome(fn () => f\compile($leading)()));
|
||||||
|
$this->assertSame($this->outcome(fn () => $middle()), $this->outcome(fn () => f\compile($middle)()));
|
||||||
|
}
|
||||||
|
|
||||||
public function testCompileWithFewerArgumentsThanPlaceholdersMatchesDecorator()
|
public function testCompileWithFewerArgumentsThanPlaceholdersMatchesDecorator()
|
||||||
{
|
{
|
||||||
$partial = f\partial(str_repeat(...), _, _);
|
$partial = f\partial(str_repeat(...), _, _);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user