เริ่มต้นด้วยคำจำกัดความที่น่ารัก
x = 1 : map (2*) x
ซึ่งโดยตัวของมันเองนั้นเป็นเรื่องที่น่าเหลือเชื่อหากคุณไม่เคยเห็นมาก่อน อย่างไรก็ตามมันเป็นเคล็ดลับที่ค่อนข้างเป็นมาตรฐานของความเกียจคร้านและการเรียกซ้ำ ตอนนี้เราจะกำจัดการเรียกซ้ำอย่างชัดเจนโดยใช้fix
และแบบไม่มีจุด
x = fix (\vs -> 1 : map (2*) vs)
x = fix ((1:) . map (2*))
สิ่งต่อไปที่เราจะทำคือขยาย:
ส่วนและทำให้map
ซับซ้อนโดยไม่จำเป็น
x = fix ((:) 1 . (map . (*) . (*2)) 1)
1
ดีตอนนี้เรามีสองฉบับอย่างต่อเนื่องว่า นั่นจะไม่เกิดขึ้นดังนั้นเราจะใช้แอพพลิเคชั่นผู้อ่านเพื่อยกเลิกการทำซ้ำ นอกจากนี้องค์ประกอบของฟังก์ชันยังเป็นขยะเล็กน้อยดังนั้นให้แทนที่ด้วย(<$>)
ทุกที่ที่ทำได้
x = fix (liftA2 (.) (:) (map . (*) . (*2)) 1)
x = fix (((.) <$> (:) <*> (map . (*) . (*2))) 1)
x = fix (((<$>) <$> (:) <*> (map <$> (*) <$> (*2))) 1)
ถัดไป: คำเรียกmap
นั้นอ่านได้มากเกินไป แต่ไม่มีอะไรต้องกลัวเราสามารถใช้กฎหมาย monad เพื่อขยายความได้เล็กน้อย โดยเฉพาะอย่างยิ่งfmap f x = x >>= return . f
ดังนั้น
map f x = x >>= return . f
map f x = ((:[]) <$> f) =<< x
เราสามารถชี้ได้โดยไม่ต้องมีค่าใช้จ่ายแทนที่(.)
ด้วย(<$>)
แล้วเพิ่มส่วนปลอมบางส่วน:
map = (=<<) . ((:[]) <$>)
map = (=<<) <$> ((:[]) <$>)
map = (<$> ((:[]) <$>)) (=<<)
การแทนที่สมการนี้ในขั้นตอนก่อนหน้า:
x = fix (((<$>) <$> (:) <*> ((<$> ((:[]) <$>)) (=<<) <$> (*) <$> (*2))) 1)
สุดท้ายคุณทำลายสเปซบาร์ของคุณและสร้างสมการสุดท้ายที่ยอดเยี่ยม
x=fix(((<$>)<$>(:)<*>((<$>((:[])<$>))(=<<)<$>(*)<$>(*2)))1)