Đây là phần tiếp theo cho câu trả lời cho câu hỏi trước của tôi.
Giả sử tôi cần ánh xạ từng mục a:A
của List[A]
đến b:B
với hàm def f(a:A, leftNeighbors:List[A]): B
và tạo List[B]
.
Rõ ràng là tôi không thể chỉ gọi map
trên danh sách mà tôi có thể sử dụng khóa kéo danh sách . Khóa kéo là một con trỏ để di chuyển xung quanh danh sách. Nó cung cấp quyền truy cập vào phần tử hiện tại ( focus
) và các phần tử lân cận của nó.
Bây giờ tôi có thể thay thế my f
bằng def f'(z:Zipper[A]):B = f(z.focus, z.left)
và chuyển hàm mới này f'
sang cobind
phương thức của Zipper[A]
.
Các cobind
hoạt động như thế này: nó gọi như vậy f'
với dây kéo, sau đó di chuyển dây kéo, gọi f'
với dây kéo mới "đã di chuyển", di chuyển dây kéo một lần nữa, vân vân ... cho đến khi dây kéo đến cuối danh sách.
Cuối cùng, cobind
trả về một loại khóa kéo mới Zipper[B]
, có thể được chuyển đổi thành danh sách và do đó vấn đề được giải quyết.
Bây giờ hãy lưu ý sự đối xứng giữa cobind[A](f:Zipper[A] => B):Zipper[B]
và bind[A](f:A => List[B]):List[B]
Đó là lý do tại sao List
a Monad
và Zipper
là a Comonad
.
Nó có ý nghĩa không?