Anonymous recursive PHP functions
是否可以使用递归和匿名的PHP函数? 这是我试图让它工作,但它没有传递函数名称。
1 2 3 4 5 | $factorial = function( $n ) use ( $factorial ) { if( $n <= 1 ) return 1; return $factorial( $n - 1 ) * $n; }; print $factorial( 5 ); |
我也知道这是实现阶乘的一种不好的方法,它只是一个例子。
为了使其工作,您需要传递$ factorial作为参考
1 2 3 4 5 | $factorial = function( $n ) use ( &$factorial ) { if( $n == 1 ) return 1; return $factorial( $n - 1 ) * $n; }; print $factorial( 5 ); |
我知道这可能不是一个简单的方法,但我从函数式语言中学到了一种称为"修复"的技术。来自Haskell的
固定点是由函数保持不变的值:函数f的固定点是任何x,使得x&nbsp; =&nbsp; f(x)。定点组合器y是返回任何函数f的固定点的函数。由于y(f)是f的固定点,我们有y(f)&nbsp; =&nbsp; f(y(f))。
本质上,Y组合器创建一个新函数,它接受原始的所有参数,以及一个附加参数,即递归函数。使用curry表示法,这是如何工作的更明显。而不是在括号(
由于PHP不会自动调整函数,因此使
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function fix( $func ) { return function() use ( $func ) { $args = func_get_args(); array_unshift( $args, fix($func) ); return call_user_func_array( $func, $args ); }; } $factorial = function( $func, $n ) { if ( $n == 1 ) return 1; return $func( $n - 1 ) * $n; }; $factorial = fix( $factorial ); print $factorial( 5 ); |
请注意,这与其他人发布的简单闭包解决方案几乎相同,但函数
虽然它不适合实际使用,但C级扩展mpyw-junks / phpext-callee提供匿名递归而不分配变量。
1 2 3 4 5 6 7 | <?php var_dump((function ($n) { return $n < 2 ? 1 : $n * callee()($n - 1); })(5)); // 5! = 5 * 4 * 3 * 2 * 1 = int(120) |
您可以在PHP 7.1+中使用Y Combinator,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | function Y ($le) {return (function ($f) {return $f($f); })(function ($f) use ($le) {return $le(function ($x) use ($f) {return $f($f)($x); }); }); } $le = function ($factorial) {return function ($n) use ($factorial) {return $n < 2 ? $n : $n * $factorial($n - 1); }; }; $factorial = Y($le); echo $factorial(1) . PHP_EOL; // 1 echo $factorial(2) . PHP_EOL; // 2 echo $factorial(5) . PHP_EOL; // 120 |
玩它:https://3v4l.org/7AUn2
源代码来自:https://github.com/whitephp/the-little-phper/blob/master/src/chapter_9.php
在较新版本的PHP中,您可以这样做:
1 2 3 4 5 6 7 8 9 10 | $x = function($depth = 0) { if($depth++) return; $this($depth); echo"hi "; }; $x = $x->bindTo($x); $x(); |
这可能会导致奇怪的行为。