Понимание того, почему молния-это Комонада
это продолжение ответа на мой предыдущий вопрос.
предположим, мне нужно сопоставить каждый элемент a:A
на List[A]
to 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]
.
The 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
.
имеет ли это смысл ?
1 ответ:
поскольку этот вопрос регулярно появляется в верхней части списка" без ответа", позвольте мне просто скопировать мой комментарий в качестве ответа здесь - ничего значительно более конструктивного не появилось с года назад в любом случае.
A
List
можно рассматривать как комонаду так же хорошо (несколькими способами), в то время какZipper
может быть брошен как монада (также во многих отношениях). Разница заключается в том, что вы концептуально ориентированы на конструктивное "добавление" данных в конечный автомат (это что заMonad
интерфейс примерно), или "извлечение" состояния из него "деконструктивно" (вот что такоеComonad
делает).нелегко ответить на вопрос, заявленный как "имеет ли это понимание смысл", однако. В каком-то смысле это так, в другом-нет.