簡體   English   中英

Haskell:關於hackage Control.Applicative文章中應用函子法的描述中的缺陷?:它說Applicative確定了Functor

[英]Haskell: Flaw in the description of applicative functor laws in the hackage Control.Applicative article?: it says Applicative determines Functor

我想我在Control.Applicative的hackage文章中發現了一個漏洞。 作為應用仿函數法的描述,它說:

 class Functor f => Applicative f where 

帶應用程序的仿函數,提供嵌入純表達式( pure )的操作,以及序列計算並組合它們的結果( <*> )。

最小完整定義必須包括滿足以下法則的這些函數的實現:

身分

 pure id <*> v = v 

組成

 pure (.) <*> u <*> v <*> w = u <*> (v <*> w) 

同態

 pure f <*> pure x = pure (fx) 

互換

 u <*> pure y = pure ($ y) <*> u 

(請注意,這並沒有說明fmap)並且它聲明這些法則確定了Functor實例:

作為這些定律的結果,f的Functor實例將滿足

 fmap fx = pure f <*> x 

我一開始以為這顯然是錯的。 也就是說,我猜一定存在一個類型構造t滿足以下兩個條件:

  1. t是實現上述規則的Applicative的實例,並且
  2. instance (Functor t)有兩種不同的實現instance (Functor t) (即有兩個不同的函數fmap1, fmap2 :: (a->b) -> (t a->tb) ,滿足函子定律)。

如果(且僅當)上述內容正確,則必須重寫上述語句

f的Functor實例必須滿足

 fmap fx = pure f <*> x 

由於這些法律,這符合Functor法律。

這顯然是正確的, 無論我的猜測是否正確

我的問題是我猜是正確的嗎? 是否有一個t與所需的條件是什么?


以下是我自己在試圖回答這個問題時的想法。

如果我們僅僅是數學家對實際的Haskell編程不感興趣 ,我們可以很容易地肯定地回答這個問題。 事實上,

t = Identity
newtype Identity a = Identity {runIdentity :: a}

符合上面的要求1和2(事實上,幾乎任何事情都可以)。 實際上, Identity是一個FunctorApplicative的實例,如Data.Functor.Identity所定義。 (這滿足fmap f = (pure f <*>) 。)為了定義instance (Functor f)另一個“實現” instance (Functor f) ,對於每個類型a ,Take,兩個函數

transf_a, tinv_a :: a -> a

這樣的

tinv_a . transf_a = id

(從理論上講 ,這很容易)。 現在定義

instance (Functor Identity) where
 fmap (f :: a->b) = Identity . transf_b . f . tinv_a . runIdentity

這符合Functor法則,如果有的話,它是與瑣碎的法則不同的實現

x :: a
f :: a -> b

這樣的

f x /= transf_b $ f $ tinv_a x

但是我們是否可以在Haskell中做到這一點並不明顯。 是這樣的:

class (Isom a) where
 transf, tinv :: a -> a

instance (Isom a) where
 transf = id
 tinv = id

specialized instance (Isom Bool) where
 transf = not
 tinv = not

可能在Haskell?


編輯

我忘了寫一些非常重要的東西。 我認為Control.Applicative是GHC基礎包的一部分,所以我也對我的問題的答案是否隨任何GHC語言擴展而改變感興趣,例如我還不了解的FlexibleInstancesOverlappingInstances

Haskell中的任何類型最多只能有一個Functor實例,所以你的猜測是不正確的:因為沒有類型t可以存在兩個不同的instance (Functor t)實現instance (Functor t) 見: http//article.gmane.org/gmane.comp.lang.haskell.libraries/15384

它是a a -> a類型的屬性,它只有兩個居民,即id :: a -> a (定義為id x = x )和bottom :: a -> a定義為bottom = error "Infinite loop."

如果我們僅將第一種情況局限於“合理”,我們得出一個重要的數學定理,即至少有一個類型為forall a. forall b. (a -> b) -> fa -> fb函數fmap forall a. forall b. (a -> b) -> fa -> fb forall a. forall b. (a -> b) -> fa -> fb forall a. forall b. (a -> b) -> fa -> fb滿足fmap id = idfmap f . fmap g = fmap (f . g) fmap f . fmap g = fmap (f . g)

如果我們不這樣做,那么你是正確的,我們有一個案例,其中fmap = undefined ,另一個fmap = (<*>) . pure fmap = (<*>) . pure 但那有點俗氣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM