Ceci fait suite à la réponse à ma question précédente.
Supposons que je doive mapper chaque élément a:A
de List[A]
à b:B
avec une fonction def f(a:A, leftNeighbors:List[A]): B
et générer List[B]
.
Évidemment, je ne peux pas simplement appeler map
sur la liste, mais je peux utiliser la fermeture à glissière de la liste . La fermeture éclair est un curseur pour se déplacer dans une liste. Il donne accès à l'élément courant ( focus
) et à ses voisins.
Maintenant, je peux remplacer mon f
par def f'(z:Zipper[A]):B = f(z.focus, z.left)
et passer cette nouvelle fonction f'
à la cobind
méthode de Zipper[A]
.
Les cobind
œuvres comme celle - ci: il appelle que f'
la fermeture à glissière, puis déplace la fermeture, les appels f'
à la nouvelle « émeut » fermeture éclair, se déplace à nouveau la fermeture éclair et ainsi de suite, et ainsi de suite ... jusqu'à ce que la fermeture à glissière atteint la fin de la liste.
Enfin, le cobind
renvoie une nouvelle fermeture éclair de type Zipper[B]
, qui peut être transformée en liste et ainsi le problème est résolu.
Notez maintenant la symétrie entre cobind[A](f:Zipper[A] => B):Zipper[B]
et bind[A](f:A => List[B]):List[B]
C'est pourquoi List
est a Monad
et Zipper
est a Comonad
.
Est-ce que ça fait du sens ?