了解为什么Zipper是一个Comonad [英] Understanding why Zipper is a Comonad
问题描述
这是对我以前的问题的回答的后续。
假设我需要将列表[A]
的每个项目 a:A
映射到 b:B
与函数 def f(a:A,leftNeighbors:List [A]):B
并生成 List [B]
。
显然,我不能直接调用 map
该列表,但我可以使用列表 zipper 。拉链是一个在列表中移动的光标。它提供对当前元素( focus
)及其邻居的访问。
现在我可以用 最后, def f'替换我的
并将这个新函数 f
(z:Zipper [A ]):B = f(z.focus,z.left) f'
传递给 cobind
。 Zipper [A]
的方法
$ b $ f'$ c $然后移动拉链,用新的移动拉链调用
f'
,再次移动拉链等等,依此类推......直到拉链到达列表的末尾。
cobind
返回一个新的类型为 Zipper [B]的拉链
$ b
现在注意 cobind [A]之间的对称性,它可以被转换为列表, (f:Zipper [A] => B):Zipper [B]
和 bind [A](f:A => List [B] B]
这就是为什么 List 是
Monad
和 Zipper
是一个 Comonad
。
是否合理?
$ b $因为这个问题经常在未回答列表的顶部出现,所以让我把我的评论作为答案复制在这里 - 什么都不是。 A List
可以被视为一个comonad也是一样(以多种方式),而 Zipper
可以作为monad(也有很多方式)投射。不同之处在于你是否在概念上专注于将数据建设性地附加到状态机(这就是 Monad
接口所关注的内容)或从中提取状态解构主义(这就是 Comonad
的作用)。
要回答这个问题并不容易,这种理解是否有意义,但是。从某种意义上说,它确实存在,而在另一种情况下则不然。
This is a follow-up to the answer to my previous question.
Suppose I need to map each item a:A
of List[A]
to b:B
with function def f(a:A, leftNeighbors:List[A]): B
and generate List[B]
.
Obviously I cannot just call map
on the list but I can use the list zipper. The zipper is a cursor to move around a list. It provides access to the current element (focus
) and its neighbors.
Now I can replace my f
with def f'(z:Zipper[A]):B = f(z.focus, z.left)
and pass this new function f'
to cobind
method of Zipper[A]
.
The cobind
works like this: it calls that f'
with the zipper, then moves the zipper, callsf'
with the new "moved" zipper, moves the zipper again and so on, and so on ... until the zipper reaches the end of the list.
Finally, the cobind
returns a new zipper of type Zipper[B]
, which can be transformed to the list and so the problem is solved.
Now note the symmetry between cobind[A](f:Zipper[A] => B):Zipper[B]
and bind[A](f:A => List[B]):List[B]
That's why List
is a Monad
and Zipper
is a Comonad
.
Does it make sense ?
As this question is popping up regularly in the top of the "unanswered" list, let me just copy my comment as an answer here - nothing considerably more constructive has appeared since a year ago anyway.
A List
can be viewed as a comonad just as well (in multiple ways), while a Zipper
can be cast as a monad (also in many ways). The difference is in whether you are conceptually focused on "appending" data constructively to a state machine (that's what the Monad
interface is about), or "extracting" state from it "deconstructively" (that's what the Comonad
does).
It is not easy to answer the question, stated as "does this understanding make sense", however. In some sense it does, in another it does not.
这篇关于了解为什么Zipper是一个Comonad的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!