Esta é uma continuação da resposta à minha pergunta anterior.
Suponha que eu precise mapear cada item a:Ade List[A]para b:Bcom função def f(a:A, leftNeighbors:List[A]): Be gerar List[B].
Obviamente, não posso apenas chamar mapa lista, mas posso usar o zíper da lista . O zíper é um cursor para mover em uma lista. Ele fornece acesso ao elemento atual ( focus) e seus vizinhos.
Agora posso substituir o meu fpor def f'(z:Zipper[A]):B = f(z.focus, z.left)e passar essa nova função f'para o cobindmétodo de Zipper[A].
As cobindfunciona assim: ele chama a f'com o zíper, então move o zíper, chamadas f'com o novo "movidos" zipper, move o zíper de novo e assim por diante, e assim por diante ... até o zíper chega ao fim da lista.
Por fim, o cobindretorna um novo zíper do tipo Zipper[B], que pode ser transformado para a lista e assim o problema é resolvido.
Agora observe a simetria entre cobind[A](f:Zipper[A] => B):Zipper[B]e bind[A](f:A => List[B]):List[B]é por isso que Listé um Monade Zipperé um Comonad.
Isso faz sentido ?