重要的是,如果您可以使用其他类型的东西,而不仅仅是extract
。直观地说,如果你能做的唯一事情就是提取值,那么类型只保存一个值,所以复制那个值就是复制所有的东西。这通常不是真实的,拉链不是这样。
Comonad
法律只是w a -> b
类型的功能变相的类别法律。由于这些来自类别,因此就类别而言可能比根据Comonad
法则更容易推理它们。 extract
是此类别的标识,并且=<=
是组合运算符。
-- | Right-to-left 'Cokleisli' composition
(=<=) :: Comonad w => (w b -> c) -> (w a -> b) -> w a -> c
f =<= g = f . extend g
我们也知道,extend f = fmap f . duplicate
,所以我们可以写
f =<= g = f . fmap g . duplicate
这看起来很容易推理。现在,让我们为您的Z
类型配备另一个我们可以谈论的功能。 isFirst
只有在Z
表示一个列表中某个位置上的某个值时才会返回true,前面没有任何值。
isFirst :: Z a -> Bool
isFirst (Z [] _ _) = True
isFirst _ = False
现在,让我们来看看会发生什么,当我们使用isFirst
与三个类别的法律。似乎只有两个立即适用于它extract
是由=<=
组成的左和右身份。既然我们只是在反驳这一点,我们只需要找到一个反例。我怀疑extract =<= isFirst
或isFirst =<= extract
之一会因输入Z [1] 2 []
而失败。这两者应该与isFirst $ Z [1] 2 []
相同,即False
。我们将首先尝试extract =<= isFirst
,这恰好可以解决。
extract =<= isFirst $ Z [1] 2 []
extract . fmap isFirst . duplicate $ Z [1] 2 []
extract . fmap isFirst $ Z [] (Z [1] 2 []) []
extract $ Z [] (isFirst (Z [1] 2 [])) []
extract $ Z [] False []
False
当我们尝试isFirst =<= extract
我们不会那么幸运。
isFirst =<= extract $ Z [1] 2 []
isFirst . fmap extract . duplicate $ Z [1] 2 []
isFirst . fmap extract $ Z [] (Z [1] 2 []) []
isFirst $ Z [] (extract (Z [1] 2 [])) []
isFirst $ Z [] 2 []
True
当我们duplicate
d我们失去了对结构的信息。事实上,除了拉链的单一焦点之外,我们失去了到处传播的所有信息。正确的duplicate
在上下文中的每个位置都有一个“拉链”,它在该位置和该位置的上下文中保存该值。
让我们看看我们可以从这些法则中推论出什么。用一个小手挥动功能类别,我们可以看到=<= extract
是fmap extract . duplicate
,这需要是身份函数。显然,我重新发现了如何在Control.Category
的文档中编写法律。这让我们写类似
z = (=<= extract) z
z = fmap extract . duplicate $ z
现在,z
只有一个构造函数,所以我们可以替换,在
Z left x right = fmap extract . duplicate $ Z left x right
从他们输入重复的,我们知道它必须返回相同的构造。
Z left x right = fmap extract $ Z lefts (Z l x' r) rights
如果我们将fmap
这个Z
我们
Z left x right = Z (fmap extract lefts) (extract (Z l x' r)) (fmap extract rights)
如果我们分手这件事由Z
构造的部分,我们有三个方程
left = fmap extract lefts
x = extract (Z l x' r)
right = fmap extract rights
这就告诉我们,至少duplicate (Z left x right)
的结果必须成立:
- 具有相同长度的左侧的列表作为
left
- 在中间
x
一个Z
用于与相同的长度right
用于右侧
中间
列表此外,我们可以看到左侧和右侧列表中的中间值必须与那些列表中的原始值相同。考虑到这一条法则,我们足够了解duplicate
的结果要求不同的结构。
你可能会对这个问题感兴趣,这个问题是关于一般为任何可区分类型派生用于拉链的comonad实例的。 http://stackoverflow.com/q/25554062/414413如果是这样,请检查pigworker广泛的解决方案与偏微分方程或我的解决方案与二阶导数。 – Cirdec 2014-12-03 20:43:39
感谢您的链接,当我试图找到我的问题的答案时,我滚动它,但现在当您明确推荐它时,我发现它有大量新东西供我思考。我肯定会研究它。 – Jackie 2014-12-05 09:58:12