นี่คือการติดตามคำตอบสำหรับคำถามก่อนหน้าของฉัน
สมมติว่าฉันต้อง map แต่ละรายการa:A
ของList[A]
ที่จะb:B
มีฟังก์ชั่นและสร้างdef f(a:A, leftNeighbors:List[A]): B
List[B]
เห็นได้ชัดว่าฉันไม่สามารถโทรmap
เข้ารายการได้ แต่ฉันสามารถใช้ซิปรายชื่อได้ ซิปเป็นเคอร์เซอร์เพื่อเลื่อนไปรอบ ๆ รายการ ให้การเข้าถึงองค์ประกอบปัจจุบัน ( focus
) และเพื่อนบ้าน
ตอนนี้ฉันสามารถแทนที่ของฉันf
ด้วย def f'(z:Zipper[A]):B = f(z.focus, z.left)
และผ่านฟังก์ชั่นใหม่นี้f'
จะใช้วิธีการcobind
Zipper[A]
การcobind
ทำงานในลักษณะนี้: เรียกสิ่งนั้นf'
ด้วยซิปจากนั้นเลื่อนซิปเรียกf'
ด้วยซิปใหม่ "ย้าย" เลื่อนซิปอีกครั้งและอื่น ๆ ... จนกระทั่งซิปไปถึงจุดสิ้นสุดของรายการ
ในที่สุดการcobind
ส่งคืนประเภทซิปใหม่Zipper[B]
ซึ่งสามารถเปลี่ยนเป็นรายการและเพื่อให้ปัญหาได้รับการแก้ไข
ตอนนี้สังเกตความสมมาตรระหว่างcobind[A](f:Zipper[A] => B):Zipper[B]
และbind[A](f:A => List[B]):List[B]
นั่นคือเหตุผลที่List
a Monad
และZipper
เป็นComonad
.
มันเข้าท่าไหม?