[英]Applicative: Prove `pure f <*> x = pure (flip ($)) <*> x <*> pure f`
在我對Typoclassopedia的研究中,我遇到了這個證據,但我不確定我的證據是否正確。 問題是:
人們可能會想到交換法的一種變體,它說的是將純函數應用於有效的論證。 使用上述法律,證明:
pure f <*> x = pure (flip ($)) <*> x <*> pure f
如果“上述法律”指向適用法律 ,請簡要說明:
pure id <*> v = v -- identity law
pure f <*> pure x = pure (f x) -- homomorphism
u <*> pure y = pure ($ y) <*> u -- interchange
u <*> (v <*> w) = pure (.) <*> u <*> v <*> w -- composition
我的證據如下:
pure f <*> x = pure (($) f) <*> x -- identical
pure f <*> x = pure ($) <*> pure f <*> x -- homomorphism
pure f <*> x = pure (flip ($)) <*> x <*> pure f -- flip arguments
您的證明的前兩個步驟看起來很好,但最后一步沒有。 雖然flip
的定義允許您使用如下法則:
f a b = flip f b a
這並不意味着:
pure f <*> a <*> b = pure (flip f) <*> b <*> a
事實上,這一般是錯誤的。 比較這兩行的輸出:
pure (+) <*> [1,2,3] <*> [4,5]
pure (flip (+)) <*> [4,5] <*> [1,2,3]
如果您需要提示,您將需要在某個時候使用原始的交換法來證明這種變體。
事實上,我發現我必須使用同態,交換和組合定律來證明這一點,並且部分證明非常棘手,尤其是使得部分正確 - 類似($ f)
,這與(($) f)
($ f)
不同(($) f)
。 讓GHCi打開以仔細檢查我的證明類型的每一步都檢查並給出正確的結果是有幫助的。 (您上面的證據類型檢查正常;這只是最后一步沒有合理性。)
> let f = sqrt
> let x = [1,4,9]
> pure f <*> x
[1.0,2.0,3.0]
> pure (flip ($)) <*> x <*> pure f
[1.0,2.0,3.0]
>
我最后向后證明了這一點:
pure (flip ($)) <*> x <*> pure f
= (pure (flip ($)) <*> x) <*> pure f -- <*> is left-associative
= pure ($ f) <*> (pure (flip ($)) <*> x) -- interchange
= pure (.) <*> pure ($ f) <*> pure (flip ($)) <*> x -- composition
= pure (($ f) . (flip ($))) <*> x -- homomorphism
= pure (flip ($) f . flip ($)) <*> x -- identical
= pure f <*> x
最后一次轉換的解釋:
flip ($)
有a -> (a -> c) -> c
類型a -> (a -> c) -> c
,直觀地說,它首先接受一個類型為a
的參數,然后是一個接受該參數的函數,最后它用第一個參數調用該函數。 因此, flip ($) 5
將一個函數作為參數,該函數以5
作為參數調用。 如果我們傳遞(+ 2)
到flip ($) 5
,我們得到flip ($) 5 (+2)
,相當於表達式(+2) $ 5
,評估為7
。
flip ($) f
相當於\\x -> x $ f
,這意味着它將一個函數作為輸入,並以函數f
作為參數調用它。
這些函數的組成如下:第一個flip ($)
將x
作為它的第一個參數,並返回一個函數flip ($) x
,這個函數正在等待函數作為它的最后一個參數,它將被調用x
作為它的論點。 現在這個函數flip ($) x
被傳遞給flip ($) f
,或者寫它的等價物(\\x -> x $ f) (flip ($) x)
,這導致表達式(flip ($) x) f
,相當於f $ x
。
你可以檢查flip ($) f . flip ($)
的類型flip ($) f . flip ($)
flip ($) f . flip ($)
是這樣的(取決於你的函數f
):
λ: let f = sqrt
λ: :t (flip ($) f) . (flip ($))
(flip ($) f) . (flip ($)) :: Floating c => c -> c
我會注意到這樣的定理通常在用幺正函子的數學風格編寫時很少涉及,而不是應用版本,即具有相同的類
class Functor f => Monoidal f where
pure :: a -> f a
(⑂) :: f a -> f b -> f (a,b)
那么法律就是
id <$> v = v
f <$> (g <$> v) = f . g <$> v
f <$> pure x = pure (f x)
x ⑂ pure y = fmap (,y) x
a⑂(b⑂c) = assoc <$> (a⑂b)⑂c
其中assoc ((x,y),z) = (x,(y,z))
。
該定理然后讀
pure u ⑂ x = swap <$> x ⑂ pure u
證明:
swap <$> x ⑂ pure u
= swap <$> fmap (,u) x
= swap . (,u) <$> x
= (u,) <$> x
= pure u ⑂ x
□
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.