簡體   English   中英

函子,應用函子和Monad之間的關系

[英]Relationship between Functor, Applicative Functor, and Monad

在閱讀類型類時,我發現函子,應用函子和Monads之間的關系是嚴格提高能力的。 函子是可以映射的類型。 應用函子可以執行相同的操作並具有一定的效果。 單聲道的效果可能不受限制 此外:

Every Monad is an Applicative Functor
Every Applicative Functor is a Functor

應用函子的定義清楚地表明了這一點:

class Functor f => Applicative f where
  pure  :: a -> f a
  (<*>) :: f (a -> b) -> f a -> f b

但是Monad的定義是:

class Monad m where
  return :: a -> m a
  (>>=)  :: m a -> (a -> m b) -> m b
  (>>)   :: m a -> m b -> m b
  m >> n = m >>= \_ -> n
  fail   :: String -> m a

根據布倫特·約吉(Brent Yorgey)的偉大的typeclassopedia ,對monad的另一種定義可能是:

class Applicative m => Monad' m where
  (>>=) :: m a -> (a -> m b) -> m b

這顯然更簡單, 並且可以鞏固Functor <Applicative Functor <Monad。 那么,為什么不定義呢? 我知道應用函子是新功能,但是根據2010年Haskell報告第80頁,這沒有改變。 為什么是這樣?

每個人都希望看到Applicative成為Monad的超類,但它會破壞太多的代碼(如果消除了return ,則每個Monad實例都將變為無效),因此每個人都希望推遲,直到我們以避免破壞的方式擴展語言為止代碼( 請參閱此處獲取一項重要建議)。

Haskell 2010總體上是保守的,漸進式的改進,僅標准化了一些無爭議的擴展,並打破了一個領域的兼容性,以使該標准與所有現有實現保持一致。 確實,Haskell 2010的庫甚至不包含Applicative-人們對標准庫的期望是標准化的,比您期望的要少。

希望我們會很快看到這種情況有所改善,但值得慶幸的是,這通常只是輕微的不便(必須在通用代碼中編寫liftM而不是fmap等)。

此時更改Monad的定義,將使很多現有代碼(定義Monad實例的任何代碼段)變得值得。

只有在這種改變有很大的實際利益的情況下,打破這種向后兼容的做法才是值得的。 在這種情況下,收益不是那么大(無論如何基本上都是理論上的收益),並且也不能證明這種破損是合理的。

暫無
暫無

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

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