Это продолжение ответа на мой предыдущий вопрос.
Предположим , что мне нужно отобразить каждый элемент 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
.
Имеет ли это смысл ?