首页 文章

可穿越#mapM&序列 - 必要吗?

提问于
浏览
1

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'

如果我的 mapMsequence' 的实现是正确的,并且,因为每个Monad都是一个Applicative:

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

那么我不清楚为什么 mapMsequence' 甚至是必要的 . 他们为什么?

附: - 感谢haoformayor帮助我sequenceA .

1 回答

  • 5

    正如评论中所提到的,有一段时间不是每个_654168都是 Applicative . 就在最近(在 base-4.8 中随GHC 7.10发货), Applicative 成为了 Monad 的超类 . 你可能见过Applicative-Monad-Proposal, AMP .

    目前Monad of no return, MRPemail-thread)正在进行中,这将使 Monad>>Applicative*> 相同 . 哪个事件很可能会说 traverse = mapMsequence = sequenceA . 但这是一个漫长的过程,需要时间 .

    所以回答你的问题:出于历史原因 .

相关问题