scala - Understanding why Zipper is a Comonad -
this follow-up answer previous question.
suppose need map each item a:a
of list[a]
b:b
function def f(a:a, leftneighbors:list[a]): b
, generate list[b]
.
obviously cannot call map
on list can use list zipper. zipper cursor move around list. provides access current element (focus
) , neighbors.
now can replace f
def f'(z:zipper[a]):b = f(z.focus, z.left)
, pass new function f'
cobind
method of zipper[a]
.
the cobind
works this: calls f'
zipper, moves zipper, callsf'
new "moved" zipper, moves zipper again , on, , on ... until zipper reaches end of list.
finally, cobind
returns new zipper of type zipper[b]
, can transformed list , problem solved.
now note symmetry between cobind[a](f:zipper[a] => b):zipper[b]
, bind[a](f:a => list[b]):list[b]
that's why list
monad
, zipper
comonad
.
does make sense ?
as question popping regularly in top of "unanswered" list, let me copy comment answer here - nothing considerably more constructive has appeared since year ago anyway.
a list
can viewed comonad (in multiple ways), while zipper
can cast monad (also in many ways). difference in whether conceptually focused on "appending" data constructively state machine (that's monad
interface about), or "extracting" state "deconstructively" (that's comonad
does).
it not easy answer question, stated "does understanding make sense", however. in sense does, in not.
Comments
Post a Comment