ดังนั้นนี่คือการอ้างอิงถึงกระดาษโดย Meijer และอีกสองสามคนที่เรียกว่า " ฟังก์ชั่นการเขียนโปรแกรมกับกล้วย, เลนส์, ซองจดหมายและลวดหนาม " แนวคิดพื้นฐานคือเราสามารถใช้ชนิดข้อมูลแบบเรียกซ้ำ
data List = Cons Int List | Nil
และเราสามารถแยกการเรียกซ้ำออกเป็นตัวแปรชนิด
data ListF a = Cons Int a | Nil
เหตุผลที่ฉันต่อท้ายนั่นF
ก็เพราะตอนนี้เป็นนักแสดงแล้ว! นอกจากนี้ยังช่วยให้เราเลียนแบบรายการ แต่ด้วยการบิด: การสร้างรายการเราต้องซ้อนประเภทรายการ
type ThreeList = ListF (ListF (ListF Void)))
การกู้คืนรายการเดิมของเราที่เราจำเป็นต้องเก็บรังนี้เพียบ ที่จะทำให้เรามีประเภทListFF
ที่
ListF ListFF == ListFF
เมื่อต้องการทำสิ่งนี้ให้นิยาม "ชนิดจุดคงที่"
data Fix f = Fix {unfix :: f (Fix f)}
type ListFF = Fix ListF
ในการออกกำลังกายคุณควรตรวจสอบสิ่งนี้ตามสมการข้างต้นของเราตอนนี้เราสามารถกำหนดว่ากล้วย (catamorphisms) คืออะไร!
type ListAlg a = ListF a -> a
ListAlg
s เป็นประเภทของ "algebras รายการ" และเราสามารถกำหนดฟังก์ชั่นเฉพาะ
cata :: ListAlg a -> ListFF -> a
cata f = f . fmap (cata f) . unfix
เพิ่มเติมอีก
cata :: ListAlg a -> ListFF -> a
cata :: (Either () (Int, a) -> a) -> ListFF -> a
cata :: (() -> a) -> ((Int, a) -> a) -> ListFF -> a
cata :: a -> (Int -> a -> a) -> ListFF -> a
cata :: (Int -> a -> a) -> a -> [Int] -> a
ดูคุ้นเคยไหม cata
เหมือนกันกับรอยพับที่ถูกต้อง!
สิ่งที่น่าสนใจจริงๆคือเราสามารถทำสิ่งนี้ได้มากกว่ารายการประเภทใดก็ตามที่กำหนดด้วย "จุดคงที่ของนักแสดง" มีcata
และเพื่อรองรับพวกเขาทั้งหมดที่เราต้องผ่อนคลายกับลายเซ็นประเภท
cata :: (f a -> a) -> Fix f -> a
นี่เป็นแรงบันดาลใจจากทฤษฎีหมวดหมู่ที่ฉันเขียนแต่นี่คือเนื้อของด้าน Haskell