113

这是我上一个问题的答案的后续。

假设我需要将每个项目映射到a:A函数并生成。List[A]b:Bdef f(a:A, leftNeighbors:List[A]): BList[B]

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

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

像这样的cobind工作:它f'用拉链调用它,然后移动拉链,f'的“移动”拉链调用,再次移动拉链,依此类推......直到拉链到达列表的末尾。

最后,cobind返回一个新的 zipper 类型Zipper[B],可以转换为列表,这样问题就解决了。

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

是否有意义 ?

4

1 回答 1

2

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

AList也可以被视为一个comonad(以多种方式),而aZipper可以被视为一个monad(也以多种方式)。区别在于您是在概念上专注于将数据建设性地“附加”到状态机(这就是Monad接口的意义所在),还是“解构地”从其中“提取”状态(这就是Comonad所做的)。

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

于 2017-04-14T14:40:33.437 回答