keep currying when compiling curried closures
This commit is contained in:
parent
a4a51e32a1
commit
71e1b2cbdc
@ -71,6 +71,9 @@ function memoize(callable $callable)
|
||||
* Flattens a callable into a plain closure. Compilable objects (decorators, pipelines, predicates) are compiled, so
|
||||
* calling the result does not go through them, also when given as a closure of their `__invoke` (e.g. `$pipe(...)`);
|
||||
* any other callable is converted with closure().
|
||||
*
|
||||
* A closure of a curried function's `__invoke` (`$curried(...)`) is kept as it is, so it keeps currying; the compiled
|
||||
* curried function itself calls its target and does not curry further.
|
||||
*/
|
||||
function compile(callable $callable): \Closure
|
||||
{
|
||||
@ -78,7 +81,9 @@ function compile(callable $callable): \Closure
|
||||
$reflection = new \ReflectionFunction($callable);
|
||||
$bound = $reflection->getClosureThis();
|
||||
|
||||
return $bound instanceof Compilable && $reflection->getName() === '__invoke' ? $bound->compile() : $callable;
|
||||
return $bound instanceof Compilable && !$bound instanceof CurriedFunction && $reflection->getName() === '__invoke'
|
||||
? $bound->compile()
|
||||
: $callable;
|
||||
}
|
||||
|
||||
return $callable instanceof Compilable ? $callable->compile() : closure($callable);
|
||||
|
||||
@ -243,6 +243,23 @@ class CompileTest extends \PHPUnit\Framework\TestCase
|
||||
$this->assertSame($pipeline('a')('b'), f\compile($pipeline)('a')('b'));
|
||||
}
|
||||
|
||||
public function testCompiledClosureOfCurriedKeepsCurrying()
|
||||
{
|
||||
$curried = f\curry(fn ($a, $b) => "$a$b");
|
||||
|
||||
$this->assertSame('ab', f\compile($curried(...))('a')('b'));
|
||||
$this->assertSame('ab', f\compile($curried(...))('a', 'b'));
|
||||
}
|
||||
|
||||
public function testCompiledPipelineOfCurriedClosureKeepsCurrying()
|
||||
{
|
||||
$curried = f\curry(fn ($a, $b) => "$a$b");
|
||||
$pipeline = f\pipe(strtoupper(...), $curried(...));
|
||||
|
||||
$this->assertSame($pipeline('a')('b'), f\compile($pipeline)('a')('b'));
|
||||
$this->assertSame('ab', f\compile(f\pipe($curried(...), fn ($rest) => $rest('b')))('a'));
|
||||
}
|
||||
|
||||
public function testCompileUnwrapsClosureOfCompilable()
|
||||
{
|
||||
$spy = new class(strtoupper(...)) extends FunctionPipeline {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user