匿名recursionPHP函数
是否有可能是recursion和匿名的PHP函数? 这是我试图让它工作,但它不通过函数名称。
$factorial = function( $n ) use ( $factorial ) { if( $n <= 1 ) return 1; return $factorial( $n - 1 ) * $n; }; print $factorial( 5 );
我也意识到这是一个不好的方法来实现阶乘,这只是一个例子。
为了使其工作,您需要传递$ factorial作为参考
$factorial = function( $n ) use ( &$factorial ) { if( $n == 1 ) return 1; return $factorial( $n - 1 ) * $n; }; print $factorial( 5 );
我知道这可能不是一个简单的方法,但我从function语言学到了一种叫做“修复”的技术。 来自Haskell的fix
函数更一般地被称为Y组合器 ,它是最知名的定点组合器之一 。
一个固定点是一个由函数不变的值:函数f的一个固定点是任何x ,使得x = f(x)。 一个定点组合器y是一个为任意函数f返回一个固定点的函数。 由于y(f)是f的一个不动点,我们有y(f)= f(y(f))。
本质上,Y组合器创build一个新的函数,它接受原始的所有参数,加上一个附加的参数,即recursion函数。 如何使用curry表示法更明显。 不要用括号( f(x,y,...)
)来写参数,而应该在函数fxy ...
之后写出它们。 Y组合器被定义为Y f = f (Y f)
; 或者用recursion函数的单个参数Y fx = f (Y f) x
。
由于PHP不会自动地调用函数,所以fix
工作有点麻烦,但是我认为这很有趣。
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 );
请注意,这与其他人发布的简单封闭解决scheme几乎相同,但函数fix
会为您创build封闭。 定点组合器比使用闭包稍微复杂一些,但是更一般,还有其他用途。 虽然封闭方法更适合于PHP(这不是一个非常function的语言),但是最初的问题更多的是一个练习而不是生产,所以Y组合是一个可行的方法。
尽pipe不适合实际使用,但C级扩展mpyw-junks / phpext-callee提供匿名recursion而不分配variables 。
<?php var_dump((function ($n) { return $n < 2 ? 1 : $n * callee()($n - 1); })(5)); // 5! = 5 * 4 * 3 * 2 * 1 = int(120)
在较新版本的PHP中,您可以这样做:
$x = function($depth = 0) { if($depth++) return; $this($depth); echo "hi\n"; }; $x = $x->bindTo($x); $x();
这可能会导致奇怪的行为。