Tôi biết đây có thể không phải là một cách tiếp cận đơn giản, nhưng tôi đã học về một kỹ thuật gọi là "sửa chữa" từ các ngôn ngữ chức năng. Các fix
chức năng từ Haskell được biết tổng quát hơn như combinator Y , đó là một trong những nổi tiếng nhất combinators điểm cố định .
Điểm cố định là một giá trị không thay đổi bởi hàm: điểm cố định của hàm f là bất kỳ x sao cho x = f (x). Một tổ hợp điểm cố định y là một hàm trả về một điểm cố định cho bất kỳ hàm f nào. Vì y (f) là một điểm cố định của f, nên ta có y (f) = f (y (f)).
Về cơ bản, bộ kết hợp Y tạo ra một hàm mới lấy tất cả các đối số của bản gốc, cộng với một đối số bổ sung đó là hàm đệ quy. Làm thế nào điều này hoạt động rõ ràng hơn bằng cách sử dụng ký hiệu curried. Thay vì viết các đối số trong ngoặc đơn (f(x,y,...)
), hãy viết chúng sau hàm : f x y ...
. Tổ hợp Y được định nghĩa là Y f = f (Y f)
; hoặc, với một đối số duy nhất cho hàm đệ quy , Y f x = f (Y f) x
.
Vì PHP không tự động làm các chức năng cà ri , nên có một chút hack để thực hiện fix
công việc, nhưng tôi nghĩ nó thật thú vị.
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 );
Lưu ý điều này gần giống như các giải pháp đóng đơn giản mà người khác đã đăng, nhưng chức năng fix
tạo ra bao đóng cho bạn. Các tổ hợp điểm cố định phức tạp hơn một chút so với sử dụng bao đóng, nhưng tổng quát hơn và có các ứng dụng khác. Mặc dù phương thức đóng phù hợp hơn với PHP (không phải là ngôn ngữ chức năng khủng khiếp), nhưng vấn đề ban đầu chỉ là một bài tập hơn là sản xuất, do đó, tổ hợp Y là một cách tiếp cận khả thi.
global $factorial
chưa?