Це продовження відповіді на моє попереднє запитання.
Припустимо , що мені потрібно відобразити кожен елемент 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
є Monad
і Zipper
є Comonad
.
Чи є сенс?