これは簡単なアプローチではないかもしれませんが、関数型言語から「修正」と呼ばれる手法について学びました。fix
Haskell の関数は、Yコンビネーターとしてより一般的に知られています。これは、最もよく知られている固定小数点コンビネーターの 1つです。。
固定小数点は、関数によって変更されない値です。関数fの固定小数点は、x = f(x)のような任意のxです。固定小数点コンビネーターyは、関数fの固定小数点を返す関数です。y(f)はfの固定小数点であるため、y(f)= f(y(f))となります。
基本的に、Yコンビネーターは、元のすべての引数に加えて、再帰関数である追加の引数を取る新しい関数を作成します。これがどのように機能するかは、カレー表記を使用するとより明白になります。引数を括弧(f(x,y,...)
)で記述する代わりに、関数の後に記述しますf x y ...
。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 );
これは、他の人が投稿した単純なクロージャソリューションとほとんど同じですが、関数fix
がクロージャを作成することに注意してください。固定小数点コンビネーターは、クロージャーを使用するよりも少し複雑ですが、より一般的で、他の用途があります。クロージャーメソッドはPHPに適していますが(これはひどく関数型の言語ではありません)、元の問題はプロダクションよりも練習問題であるため、Yコンビネーターは実行可能なアプローチです。
global $factorial
か?