你问的问题有点结构性的谬误.它不是拉链,可以表示为Comonads,而是说它们是本质.
同样,整数只需是幺(有两种方式!)您是否选择接受这样的事实.
因此,您应该问的问题是"我可以通过识别共同结构来提高清晰度吗?"而不是询问有什么好处?
答案是"是的!"
Comonadic结构意味着在任何拉链上都存在两种有趣的方法.第一个是明显的,显然是有用的 - "这里"功能.为了使这个更具体,我将制作一个列表拉链
data Zipper a = Zipper { before :: [a], here :: a, after :: [a] }
Run Code Online (Sandbox Code Playgroud)
现在here :: Zipper a -> a是通常称为的comonadic函数extract.
extract = here
Run Code Online (Sandbox Code Playgroud)
因此,可以公平地说,每次检查拉链指向的东西时,您都在使用comonadic界面.
也就是说,extract界面是无聊的一面.更有趣的是extend.
extend :: (Zipper a -> b) -> Zipper a -> Zipper b
Run Code Online (Sandbox Code Playgroud)
什么extend捕捉在拉链应用"语境转型"的每个元素的想法.Comonadic结构指出,有一种标准且结构良好的方法可以通过" extend转换"到整个comonad来实现.
这样的例子可能是将卷积应用于列表 - 例如,一点点模糊功能:
blurKernel :: Fractional a => Zipper a -> a
blurKernel (Zipper prior current future) =
(a + current + c) / 3
where
a = case prior of
[] -> 0
(p:ps) -> p
c = case future of
[] -> 0
(p:ps) -> p
blur :: Fractional a => Zipper a -> Zipper a
blur = extend blurKernel
Run Code Online (Sandbox Code Playgroud)
那么为什么要用blur这些术语写呢?是不是有一种自然的,递归的或迭代的表达方式可以起作用并且更明显?
好吧,通过识别blur基于comonadic扩展,我们在Zippers操作中暴露了通用结构.这对维持DRY有益.
我们也开始认识到Zippers的一些深刻意义 - 每个拉链都有comonadic extend所以也许我们可以通过某种方式推广blur到所有Fractional类型的Zipper blurKernel并将extend其整合到我们关心的每个Zipper中.
在任何情况下,我希望我的例子证明Zippers是comonads,无论你是否注意到它.
这通常就是好的Haskell抽象的情况 - 它们是关于某些代码运行方式的自然属性.为方便起见,类型类仅捕获它们.Maybe/ State/ List/ etc即使不是Monads 也是monad .和Zipper/ Store/ Trace是即使他们不是comonads Comonad秒.