Я знаю, що це може бути не простий підхід, але я дізнався про техніку під назвою "виправити" з функціональних мов. fix
Функція з Haskell відома в більш загальному випадку в якості Y комбінатора , який є одним з найвідоміших точкових комбінаторів фіксованих .
Фіксована точка - це значення, яке не змінюється функцією: фіксованою точкою функції f є будь-який х, такий, що x = f (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
?