了解为什么拉链是Comonad


112

这是对上一个问题的回答的后续步骤。

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

显然,我不能只调用map列表,而可以使用列表拉链。拉链是用于在列表中移动的光标。它提供对当前元素(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]这就是为什么Lista MonadZipperis a 的原因Comonad

是否有意义 ?


1
我不是专家,但这对我来说很有意义。在阅读您的解释时,我顿悟了。谢谢!
acjay 2014年

7
您的问题很难以SO格式回答...但是您绝对正确。注重元素的拉链总是很有趣。
J. Abrahamson 2014年

4
List也可以(以多种方式)被视为comonad,而Zipper则可以以多种方式被视为monad。区别在于,您是在概念上专注于将数据构造性地“添加”到状态机(这就是Monad接口所针对的),还是从“解构性”从状态机“提取”状态(即Comonad所做的)。但是,回答这个问题并不容易,因为“这种理解是否有意义”。从某种意义上说确实如此,在另一种意义上则没有。
KT。

2
要将某事物转换为一个comonad,您需要提供两个操作:1)提取值(例如,它可能是列表的头部)和2)应用列表处理操作(例如,您可以将其应用于滑动式沿列表的窗口方式或元素方式等(假设进行适当的单位转换不会更改列表)。这种处理列表的方式是否有意义是一个单独的问题。请注意,空的comonad接口既不提供构造列表也不不能遍历列表的方法。它只知道如何使用列表感知操作。
KT。

2
@eenblam你是对的。我将添加一个答案,它将这个问题从未答复的列表中剔除,我希望
迈克尔

Answers:


1

由于这个问题经常出现在“未答复”列表的顶部,因此,我只在这里复制我的评论作为答案-自一年前以来,没有什么更具建设性的东西出现过。

List也可以将A 视为共鸣(以多种方式),而将A转换为Monad Zipper(也可以以多种方式)。区别在于,您是在概念上专注于将数据构造性地“添加”到状态机(这是Monad接口所要解决的问题),还是从“解构性”从状态机“提取”状态(即是Comonad做事)。

但是,回答这个问题并不容易,因为“这种理解是否有意义”。从某种意义上说确实如此,在另一种意义上则没有。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.