Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding why Zipper is a Comonad

This is a follow-up to the answer to my previous question.

Suppose I need to map each item a:A of List[A] to b:B with function def f(a:A, leftNeighbors:List[A]): B and generate List[B].

Obviously I cannot just call map on the list but I can use the list zipper. The zipper is a cursor to move around a list. It provides access to the current element (focus) and its neighbors.

Now I can replace my f with def f'(z:Zipper[A]):B = f(z.focus, z.left) and pass this new function f' to cobind method of Zipper[A].

The cobind works like this: it calls that f' with the zipper, then moves the zipper, callsf' with the new "moved" zipper, moves the zipper again and so on, and so on ... until the zipper reaches the end of the list.

Finally, the cobind returns a new zipper of type Zipper[B], which can be transformed to the list and so the problem is solved.

Now note the symmetry between cobind[A](f:Zipper[A] => B):Zipper[B] and bind[A](f:A => List[B]):List[B] That's why List is a Monad and Zipper is a Comonad.

Does it make sense ?

like image 344
Michael Avatar asked Jun 03 '14 10:06

Michael


1 Answers

As this question is popping up regularly in the top of the "unanswered" list, let me just copy my comment as an answer here - nothing considerably more constructive has appeared since a year ago anyway.

A List can be viewed as a comonad just as well (in multiple ways), while a Zipper can be cast as a monad (also in many ways). The difference is in whether you are conceptually focused on "appending" data constructively to a state machine (that's what the Monad interface is about), or "extracting" state from it "deconstructively" (that's what the Comonad does).

It is not easy to answer the question, stated as "does this understanding make sense", however. In some sense it does, in another it does not.

like image 101
KT. Avatar answered Oct 20 '22 08:10

KT.