2015-12-28 51 views
1

Typeclassopedia呈現Traversable的:Traversable#mapM&sequence - 必要嗎?

class (Functor t, Foldable t) => Traversable t where 
    traverse :: Applicative f => (a -> f b) -> t a -> f (t b) 
    sequenceA :: Applicative f => t (f a) -> f (t a) 
    mapM  ::  Monad m => (a -> m b) -> t a -> m (t b) 
    sequence ::  Monad m => t (m a) -> m (t a) 

一個很好的鍛鍊是要弄清楚的默認實現應該是什麼:考慮要麼橫向或sequenceA,你會如何定義其他的三種方法?

我想出了下面的代碼類型檢查:

class (Functor t, Foldable t) => MyTraversable t where 
    traverse' :: Applicative f => (a -> f b) -> t a -> f (t b) 
    traverse' = error "..." 
    sequenceA' :: Applicative f => t (f a) -> f (t a) 
    sequenceA' f = traverse' id f 
    mapM  ::  Monad m => (a -> m b) -> t a -> m (t b) 
    mapM = traverse' 
    sequence' ::  Monad m => t (m a) -> m (t a) 
    sequence' = sequenceA' 

如果我的mapMsequence'實現是正確的,而且,因爲每個單子是一個應用型:

λ: :i Monad 
class Applicative m => Monad (m :: * -> *) where 
... 

那麼我不清楚爲什麼mapMsequence'甚至是必要的。他們爲什麼?

P.S. - 信用和感謝haoformayor幫助我與sequenceA

+12

當不是每個'Monad'都是'Applicative'時,都有一段令人尷尬的時刻。 –

+8

你沒有問過這個問題,但是你應該永遠不會做一個總是產生錯誤的默認類方法。只是不要在這種情況下默認;如果該方法未在實例中定義,GHC將發出警告。假設默認情況下,用戶不會收到警告;事情在運行時就炸燬了。 – dfeuer

回答

4

正如評論中提到的,有一段時間,並非每個Monad都是Applicative。 最近(在GHC 7.10附帶的base-4.8中),Applicative被製成Monad的超類。您可能已經看過Applicative-Monad-Proposal, AMP

目前Monad of no return, MRPemail-thread)進行加工的,這將使得 Monad>>Applicative*>相同。哪些事情可以說是traverse = mapMsequence = sequenceA。但這是一個漫長的過程,需要時間。

所以要回答你的問題:由於歷史原因