了解为什么Zipper是Comonad

时间:2014-06-03 10:55:01

标签: scala functional-programming zipper comonad

这是对我之前提问的answer的跟进。

假设我需要将a:A的{​​{1}}项List[A]映射到b:B def f(a:A, leftNeighbors:List[A]): B,并生成List[B]

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

现在,我可以将f替换为def f'(z:Zipper[A]):B = f(z.focus, z.left),并将此新功能f'传递给cobind的{​​{1}}方法。

Zipper[A]的工作原理如下:它使用拉链调用cobind,然后移动拉链,使用 new “move”拉链调用f' ,再次移动拉链,依此类推......直到拉链到达列表的末尾。

最后,f'会返回cobind类型的新拉链,可以将其转换为列表,从而解决问题。

现在请注意Zipper[B]cobind[A](f:Zipper[A] => B):Zipper[B]之间的对称性。这就是bind[A](f:A => List[B]):List[B]ListMonadZipper的原因。

有意义吗?

1 个答案:

答案 0 :(得分:1)

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

List也可以被视为comonad(以多种方式),而Zipper可以被视为monad(也以多种方式)。不同之处在于你是否在概念上专注于"追加"建设性地向状态机提供数据(这是Monad接口的内容),或者提取"提取"从它的状态"解构主义" (这是Comonad的作用。)

要回答这个问题并不容易,并且说明这些理解是否有意义"然而。在某种意义上它确实如此,在另一种意义上它没有。