在this presentation 2005中,我们阅读了幻灯片32:
拉链数据类型隐藏了一个comonad。这正是构造属性计算所需要的通信量。
因此,你似乎可以表达Zippers in terms of Comonads。这看起来更像是possible in Scala。
查看zipper source,我们看到了以Clojure元数据表示的压缩器。
我的问题是,有什么证据表明Clojure会从被表示为comonad中获益?
Eric suggests的好处是
所以我们需要所有可能的拉链超过原来的组!
发布于 2014-08-19 11:51:31
你的要求有点结构性谬误。这并不是说拉链可以用Comonad来表达,而是因为它们是天生的。
类似地,整数只是一元(用两种方式!)不管你是否愿意接受这个事实。
所以,你应该问的不是什么好处,而是“我能通过识别共进结构来提高清晰度吗?”
答案是“是的!”
共进结构意味着在任何拉链上都有两种有趣的方法。第一个是显而易见的,而且显然是有用的--“这里”函数。为了使这个更具体,我会列一个拉链
data Zipper a = Zipper { before :: [a], here :: a, after :: [a] }现在,here :: Zipper a -> a是通常称为extract的共进函数。
extract = here因此,可以公平地说,每次检查拉链指向的东西时,都使用共进接口。
尽管如此,extract是界面中无聊的一面。更有趣的是extend。
extend :: (Zipper a -> b) -> Zipper a -> Zipper bextend捕获的是对拉链中的每个元素应用“上下文化转换”的想法。共进结构注意到,有一种标准的、结构良好的方法,它是通过"extending“向整个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那么,为什么要用这些术语编写blur呢?难道没有一个自然的、递归的或迭代的公式可以同样地工作并且更明显吗?
通过认识到blur是基于共进扩展的,我们已经在我们的拉链操作中公开了公共结构。这对保持干燥是有益的。
我们也开始认识到拉链有一些深刻的东西-每个拉链都有共进的extend,所以也许我们可以把blur推广到所有Fractional类型的拉链,方法是在我们关心的每个拉链中推广blurKernel和extend。
无论如何,我希望我的例子表明,无论您是否注意到,拉链都是comonad。
好的Haskell抽象通常是这样的--它们是关于某些类型代码操作方式的自然属性。类型类只是为了方便起见捕获它们。即使Maybe/State/List/etc不是Monads,它们也是单子,而Zipper/Store/Trace即使不是Comonads,也会是comonad。
https://stackoverflow.com/questions/25376192
复制相似问题