Typeclassopedia呈现Traversable:
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)
一个很好的练习是弄清楚默认实现应该是什么:给定traverse或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'
的实现是正确的,并且,因为每个Monad都是一个Applicative:
λ: :i Monad
class Applicative m => Monad (m :: * -> *) where
...
那么我不清楚为什么 mapM
和 sequence'
甚至是必要的 . 他们为什么?
附: - 感谢haoformayor帮助我sequenceA .
1 回答
正如评论中所提到的,有一段时间不是每个_654168都是
Applicative
. 就在最近(在base-4.8
中随GHC 7.10发货),Applicative
成为了Monad
的超类 . 你可能见过Applicative-Monad-Proposal, AMP .目前Monad of no return, MRP(email-thread)正在进行中,这将使
Monad
的>>
和Applicative
的*>
相同 . 哪个事件很可能会说traverse = mapM
和sequence = sequenceA
. 但这是一个漫长的过程,需要时间 .所以回答你的问题:出于历史原因 .