英文:
Currying in PHP
问题
给定的问题中,你试图在PHP中实现currying
(类似于JavaScript中的方式)。你的代码出现了问题,错误信息显示为undefined variable $curried
。你的问题是如何递归调用相同的curried函数。期望的输出应该是60
,就像在回调函数fn($x, $y, $z) => $x + $y + $z
中一样。
英文:
I am trying to implement currying
in PHP this time(just like how we do in Javascript). Below is my code which is not working:
<?php
function test(callable $fn){
$reflection = new ReflectionFunction($fn);
$args = count($reflection->getParameters());
$curried = function(...$currArgs) use($args, $fn){
if(count($currArgs) == $args){
return $fn(...$currArgs);
}else{
return function(...$currArgs2) use($args, $fn, $currArgs){
return $curried(array_merge($currArgs, $currArgs2));
};
}
};
return $curried;
}
$c = test(fn($x, $y, $z) => $x + $y + $z);
echo $c(10)(20,30);
Issue:
It is giving me undefined variable $curried
as you can see here
.
Question:
How can we recursively call the same curried function as I see no way to achieve this here?
Expected output:
The expected output should be 60
as done in the callback fn($x, $y, $z) => $x + $y + $z
答案1
得分: 1
Sure, here's the translated content:
好的,这对我来说是一个相当有趣的问题。柯里化具有良好的语法糖以及其他几个优点(比如在日志记录中,我们可以在多个DEBUG/INFO日志语句方法调用中缓存日期时间,而无需为每个日志语句传递日期时间参数)。
-
首先,在新的匿名回调内递归调用时,
$curried
是不可访问的。为了使其工作,我们需要通过引用在use
参数中传递此变量。 -
第二,似乎在回调外部计算参数计数并没有任何优势。因此,我们将其放在回调内部。
-
第三,在
$curried(array_merge($currArgs, $currArgs2))
中,我没有将它们作为可变长度的参数传递,这导致了参数计数的问题。所以,修复是$curried(...array_merge($currArgs, $currArgs2))
。
最终的工作代码:
<?php
function test(callable $fn){
$curried = function(...$currArgs) use(&$fn, &$curried){
$reflection = new ReflectionFunction($fn);
$args = count($reflection->getParameters());
if(count($currArgs) == $args){
return $fn(...$currArgs);
}else{
return function(...$currArgs2) use( $fn, $currArgs, &$curried){
return $curried(...array_merge($currArgs, $currArgs2));
};
}
};
return $curried;
}
$c = test(fn($x, $y, $z) => $x + $y + $z);
echo $c(10)(20,30), "\n";
echo $c(10,20)(30), "\n";
echo $c(10,20,30), "\n";
英文:
Ok, this has been a pretty interesting problem for me. Currying has a good syntatic sugar along with several other advantages(like in logging, we can cache the datetime across multiple DEBUG/INFO log statement method calls without having the need to pass datetime parameter for each log statement).
-
First,
$curried
is not accessible when called recursively inside the new anonymous callback. For this to work, we need to pass in this variable inuse
parameters by reference. -
Second, we don't seem to have any advantage of calculating the parameter count outside the callback. So, we put this inside the callback.
-
Third, in
$curried(array_merge($currArgs, $currArgs2))
, I wasn't passing them as variable length arguments which was causing the problem in parameter count computation. So, fix is$curried(...array_merge($currArgs, $currArgs2))
.
Final Working code:
<?php
function test(callable $fn){
$curried = function(...$currArgs) use(&$fn, &$curried){
$reflection = new ReflectionFunction($fn);
$args = count($reflection->getParameters());
if(count($currArgs) == $args){
return $fn(...$currArgs);
}else{
return function(...$currArgs2) use( $fn, $currArgs, &$curried){
return $curried(...array_merge($currArgs, $currArgs2));
};
}
};
return $curried;
}
$c = test(fn($x, $y, $z) => $x + $y + $z);
echo $c(10)(20,30),"\n";
echo $c(10,20)(30),"\n";
echo $c(10,20,30),"\n";
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论