了解为什么Zipper是Comonad

Mic*_*ael 112 functional-programming scala zipper comonad

这是对我上一个问题的答案的后续跟进.

假设我需要映射每个项目a:AList[A]b:B使用功能def f(a:A, leftNeighbors:List[A]): B和产生List[B].

显然,我不能只是map在列表上调用,但我可以使用列表拉链.拉链是一个在列表中移动的光标.它提供对当前element(focus)及其邻居的访问.

现在我可以替换我fdef f'(z:Zipper[A]):B = f(z.focus, z.left)并将这个新函数传递f'cobind方法Zipper[A].

这样的cobind工作:它f'用拉链调用,然后移动拉链,f'新的 "移动"拉链调用,再次移动拉链等等......直到拉链到达列表的末尾.

最后,cobind返回一个新的拉链类型Zipper[B],可以将其转换为列表,从而解决问题.

现在请注意之间的对称性cobind[A](f:Zipper[A] => B):Zipper[B]bind[A](f:A => List[B]):List[B]这就是为什么ListMonadZipperComonad.

是否有意义 ?

KT.*_*KT. 3

由于这个问题经常出现在“未回答”列表的顶部,让我在这里复制我的评论作为答案 - 无论如何,自一年前以来,没有出现任何更具建设性的问题。

AList也可以被视为一个共元体(以多种方式),而 aZipper可以被视为一个单子(也以多种方式)。区别在于您在概念上是否专注于将数据建设性地“附加”到状态机(这就是接口的作用Monad),或者“解构性地”从中“提取”状态(这就是接口的作用Comonad)。

然而,要回答“这种理解是否有意义”的问题并不容易。从某种意义上说是这样,从另一种意义上说不是。