Это продолжение ответа на мой предыдущий вопрос.
Предположим , что мне нужно отобразить каждый элемент 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
.
Имеет ли это смысл ?
Ответы:
Поскольку этот вопрос регулярно появляется в верхней части списка "неотвеченных", позвольте мне просто скопировать свой комментарий в качестве ответа здесь - в любом случае ничего более конструктивного с года назад не появилось.
A также
List
можно рассматривать как комонаду (несколькими способами), в то время как aZipper
можно использовать как монаду (также разными способами). Разница заключается в том, сконцентрированы ли вы на концептуальном «добавлении» данных в конечный автомат (это то, о чемMonad
идет речь в интерфейсе) или «извлечении» из него состояния «деконструктивно» (это то, чтоComonad
делает).Однако нелегко ответить на вопрос, сформулированный как «имеет ли это понимание смысл». В одном смысле да, в другом - нет.
источник