ฉันรู้ว่านี่อาจไม่ใช่วิธีที่ง่าย แต่ฉันเรียนรู้เกี่ยวกับเทคนิคที่เรียกว่า"แก้ไข"จากภาษาที่ใช้งานได้ fix
ฟังก์ชั่นจาก Haskell เป็นที่รู้จักกันมากขึ้นโดยทั่วไปเป็นCombinator Yซึ่งเป็นหนึ่งในที่สุดที่รู้จักกันดีcombinators จุดคงที่
จุดคงที่คือค่าที่ไม่เปลี่ยนแปลงโดยฟังก์ชั่น: จุดคงที่ของฟังก์ชันfคือxใด ๆที่ x = f (x) Combinator จุดคงที่yเป็นฟังก์ชั่นที่ส่งกลับจุดคงที่สำหรับฟังก์ชั่นใด ๆ f เนื่องจาก y (f) เป็นจุดคงที่ของ f เราจึงมี y (f) = f (y (f))
โดยพื้นฐานแล้ว Y combinator สร้างฟังก์ชั่นใหม่ที่รับอาร์กิวเมนต์ทั้งหมดของต้นฉบับรวมทั้งอาร์กิวเมนต์เพิ่มเติมที่เป็นฟังก์ชันเรียกซ้ำ วิธีการทำงานนี้ชัดเจนยิ่งขึ้นโดยใช้สัญกรณ์ Curried แทนการเขียนข้อโต้แย้งในวงเล็บ ( f(x,y,...)
) f x y ...
เขียนพวกเขาหลังจากที่ฟังก์ชั่น: Y combinator ถูกกำหนดให้เป็น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 combinator จึงเป็นแนวทางที่ทำงานได้
global $factorial
หรือไม่