Verstehen, warum Zipper eine Comonad ist

112

Dies ist eine Fortsetzung der Antwort auf meine vorherige Frage.

Angenommen , ich brauche jedes Element zur Karte a:Avon List[A]zu b:Bmit Funktion def f(a:A, leftNeighbors:List[A]): Bund erzeugen List[B].

Natürlich kann ich nicht einfach anrufen mapauf der Liste , aber ich kann die Liste verwenden Reißverschluss . Der Reißverschluss ist ein Cursor zum Bewegen in einer Liste. Es bietet Zugriff auf das aktuelle Element ( focus) und seine Nachbarn.

Jetzt kann ich meine fdurch ersetzen def f'(z:Zipper[A]):B = f(z.focus, z.left)und diese neue Funktion f'an die cobindMethode von übergeben Zipper[A].

Das cobindfunktioniert so: Es ruft das f'mit dem Reißverschluss auf, bewegt dann den Reißverschluss, ruft f'mit dem neuen "verschobenen" Reißverschluss auf, bewegt den Reißverschluss wieder und so weiter und so fort ... bis der Reißverschluss das Ende der Liste erreicht.

Schließlich wird cobindein neuer Reißverschluss vom Typ zurückgegeben Zipper[B], der in die Liste umgewandelt werden kann, sodass das Problem gelöst ist.

Beachten Sie nun die Symmetrie zwischen cobind[A](f:Zipper[A] => B):Zipper[B]und bind[A](f:A => List[B]):List[B]Deshalb Listist a Monadund Zipperist a Comonad.

Macht das Sinn ?

Michael
quelle
1
Ich bin kein Experte, aber das macht für mich Sinn. Ich hatte eine Offenbarung, als ich Ihre Erklärung las. Vielen Dank!
Acjay
7
Ihre Frage ist im SO-Format sehr schwer zu beantworten ... aber Sie haben absolut Recht. Elementfokussierte Reißverschlüsse sind immer Comonaden.
J. Abrahamson
4
Die Liste kann genauso gut als Comonade angesehen werden (auf verschiedene Arten), während ein Reißverschluss als Monade gegossen werden kann (auch auf viele Arten). Der Unterschied besteht darin, ob Sie sich konzeptionell darauf konzentrieren, Daten konstruktiv an eine Zustandsmaschine anzuhängen (darum geht es in der Monad-Schnittstelle) oder den Zustand "dekonstruktiv" daraus zu extrahieren (genau das tut die Comonad). Es ist jedoch nicht einfach, die Frage zu beantworten, die lautet: "Ist dieses Verständnis sinnvoll?". In gewissem Sinne tut es das, in einem anderen nicht.
KT.
2
Um etwas in eine Comonade umzuwandeln, müssen Sie zwei Operationen bereitstellen: 1) Extrahieren eines Werts (z. B. könnte es der Kopf der Liste sein) und 2) Anwenden einer Listenverarbeitungsoperation (z. B. können Sie ihn in einer gleitenden Operation anwenden). Fensterweise entlang der Liste oder auf elementweise Weise oder dergleichen, vorausgesetzt, eine geeignete Einheitentransformation ändert die Liste nicht). Ob eine solche Art der Verarbeitung einer Liste sinnvoll ist, ist eine separate Frage. Beachten Sie, dass eine nackte Comonad-Schnittstelle weder eine Möglichkeit zum Erstellen noch zum Durchlaufen der Liste bietet. Es kann nur listenorientierte Vorgänge ausführen.
KT.
2
@eenblam Du hast recht. Ich werde eine Antwort hinzufügen und es wird diese Frage von der unbeantworteten Liste bekommen, hoffe ich
Michael

Antworten:

1

Da diese Frage regelmäßig ganz oben auf der "unbeantworteten" Liste auftaucht, möchte ich hier nur meinen Kommentar als Antwort kopieren - seit einem Jahr ist ohnehin nichts wesentlich Konstruktiveres aufgetaucht.

A Listkann genauso gut als Comonade angesehen werden (auf verschiedene Arten), während A Zipperals Monade besetzt werden kann (auch in vielerlei Hinsicht). Der Unterschied besteht darin, ob Sie sich konzeptionell darauf konzentrieren, Daten konstruktiv an eine Zustandsmaschine anzuhängen ( Monaddarum geht es in der Schnittstelle) oder den Zustand "dekonstruktiv" daraus zu extrahieren (darum Comonadgeht es).

Es ist jedoch nicht einfach, die Frage zu beantworten, die lautet: "Ist dieses Verständnis sinnvoll?". In gewissem Sinne tut es das, in einem anderen nicht.

KT.
quelle