重要的是,如果您可以使用其他類型的東西,而不僅僅是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