我知道这可能不是一个简单的方法,但我从函数式语言中学到了一种名为“fix”的技术。Haskell的函数通常被称为Y组合子,它是最着名的不动点组合器之一。fix
不动点是函数不变的值:函数 f 的不动点是任何 x,使得 x = f(x)。不动点组合器 y 是返回任何函数 f 的不动点的函数。由于 y(f) 是 f 的不动点,因此我们有 y(f) = f(y(f))。
从本质上讲,Y 组合器创建了一个新函数,该函数采用原始参数的所有参数,以及递归函数的附加参数。使用咖喱符号,这是如何工作的更明显。不要在括号 () 中编写参数,而是将它们写在函数之后:。Y 组合器定义为 ;或者,使用递归函数的单个参数, 。f(x,y,...)
f x y ...
Y f = f (Y f)
Y f x = 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 );
请注意,这几乎与其他人发布的简单闭包解决方案相同,但该函数会为您创建闭包。定点组合器比使用闭包稍微复杂一些,但更通用,并且有其他用途。虽然闭包方法更适合PHP(它不是一种非常函数式的语言),但最初的问题更多的是练习而不是生产,所以Y组合器是一种可行的方法。fix