Bunun basit bir yaklaşım olmayabileceğini biliyorum, ama fonksiyonel dillerden "düzeltme" adı verilen bir teknik öğrendim . fix
Haskell fonksiyonu olarak daha genel olarak bilinen Y combinator en iyi bilinen biri, sabit nokta bağdaştırıcılarla .
Sabit nokta, bir işlev tarafından değiştirilmeyen bir değerdir: f işlevinin sabit noktası, x = f (x) olacak şekilde herhangi bir x'dir . Sabit nokta birleştiricisi y , herhangi bir işlev f için sabit nokta döndüren bir işlevdir. Y (f) sabit bir f noktası olduğundan, y (f) = f (y (f)) değerine sahibiz.
Esasen, Y birleştiricisi, orijinalin tüm argümanlarını alan yeni bir işlev ve ayrıca özyinelemeli işlev olan ek bir argüman oluşturur. Bunun nasıl çalıştığı, kavisli gösterimi kullanarak daha açıktır. Bunun yerine parantez içinde argüman yazma ( f(x,y,...)
), fonksiyonu sonra bunları yazın: f x y ...
. Y birleştiricisi Y f = f (Y f)
; veya yinelenen işlev için tek bir argümanla Y f x = f (Y f) x
.
PHP işlevleri otomatik olarak köri yapmadığından , fix
iş yapmak için bir kesmek biraz , ama ilginç olduğunu düşünüyorum.
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 );
Bunun, başkalarının gönderdiği basit kapatma çözümleriyle hemen hemen aynı olduğunu unutmayın, ancak işlev fix
sizin için kapağı oluşturur. Sabit nokta birleştiricileri, bir kapak kullanmaktan biraz daha karmaşıktır, ancak daha geneldir ve başka kullanımları vardır. Kapatma yöntemi PHP için (çok fonksiyonel bir dil değildir) daha uygun olsa da, asıl sorun üretimden çok bir alıştırmadır, bu nedenle Y birleştiricisi uygulanabilir bir yaklaşımdır.
global $factorial
mi?