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'
如果我的mapM
和sequence'
實現是正確的,而且,因爲每個單子是一個應用型:
λ: :i Monad
class Applicative m => Monad (m :: * -> *) where
...
那麼我不清楚爲什麼mapM
和sequence'
甚至是必要的。他們爲什麼?
P.S. - 信用和感謝haoformayor幫助我與sequenceA
。
當不是每個'Monad'都是'Applicative'時,都有一段令人尷尬的時刻。 –
你沒有問過這個問題,但是你應該永遠不會做一個總是產生錯誤的默認類方法。只是不要在這種情況下默認;如果該方法未在實例中定義,GHC將發出警告。假設默認情況下,用戶不會收到警告;事情在運行時就炸燬了。 – dfeuer