Compreendendo porque Zipper é um Comonad

112

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 ?

Michael
fonte
1
Não sou um especialista, mas isso faz sentido para mim. Tive uma epifania ao ler sua explicação. Obrigado!
acjay
7
Sua pergunta é muito difícil de responder no formato SO ... mas você está absolutamente correto. Zíperes focados em elementos são sempre comuns.
J. Abrahamson
4
A lista também pode ser vista como uma comonada (de várias maneiras), enquanto um Zipper pode ser lançado como uma mônada (também de várias maneiras). A diferença é se você está conceitualmente focado em "anexar" dados construtivamente a uma máquina de estado (é disso que trata a interface do Monad) ou em "extrair" o estado dela "desconstrutivamente" (é isso que o Comonad faz). Não é fácil responder à pergunta, afirmada como "esse entendimento faz sentido", no entanto. Em certo sentido, sim, em outro, não.
KT.
2
Para lançar algo em um comonad, você precisa fornecer duas operações: 1) Extração de um valor (por exemplo, pode ser o topo da lista) e 2) Aplicação de uma operação de processamento de lista (por exemplo, você pode aplicá-la em um janela ao longo da lista ou em forma de elemento ou semelhante, assumindo que uma transformação de unidade apropriada não mudará a lista). Se essa forma de processar uma lista faz algum sentido, é outra questão. Observe que uma interface comum simples não fornece uma maneira de construir a lista nem de percorrê-la. Ele só sabe como consumir operações com reconhecimento de lista.
KT.
2
@eenblam Você está certo. Acrescentarei uma resposta e isso tirará essa pergunta da lista sem respostas, espero
Michael

Respostas:

1

Como esta pergunta está aparecendo regularmente no topo da lista de "não respondidas", deixe-me apenas copiar meu comentário como uma resposta aqui - nada muito mais construtivo apareceu desde um ano atrás, de qualquer maneira.

A também Listpode ser visto como uma comonada (de várias maneiras), enquanto a Zipperpode ser lançado como uma mônada (também de várias maneiras). A diferença é se você está conceitualmente focado em "anexar" dados construtivamente a uma máquina de estado (é disso que Monadtrata a interface) ou em "extrair" o estado dela "desconstrutivamente" (é isso que Comonadela faz).

Não é fácil responder à pergunta, afirmada como "esse entendimento faz sentido", no entanto. Em certo sentido, sim, em outro, não.

KT.
fonte