Haskell 可遍历的#mapM&;顺序-必要吗?
呈现可遍历的:Haskell 可遍历的#mapM&;顺序-必要吗?,haskell,Haskell,呈现可遍历的: 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
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都是一个应用程序:
λ: :i Monad
class Applicative m => Monad (m :: * -> *) where
...
我不清楚为什么mapM
和sequence'
是必要的。为什么会这样
附言-感谢您帮助我解决问题。如评论中所述,曾经有一段时间,并不是每个
单子都是应用程序。
最近(在GHC 7.10附带的base-4.8
中,Applicative
成为Monad
的超类。你可能已经看到了
当前()正在处理中,这将使
Monad
>
和Applicative
的*>
相同。这最终会使我们有可能说traverse=mapM
和sequence=sequenceA
。但这是一个漫长的过程,需要时间
因此,为了回答您的问题:出于历史原因。正如评论中提到的,曾经有一段时间,并不是每个单子都是应用程序。
最近(在GHC 7.10附带的base-4.8
中,Applicative
成为Monad
的超类。你可能已经看到了
当前()正在处理中,这将使
Monad
>
和Applicative
的*>
相同。这最终会使我们有可能说traverse=mapM
和sequence=sequenceA
。但这是一个漫长的过程,需要时间
所以要回答你的问题:出于历史原因。有一段尴尬的时期,不是每个Monad
都是Applicative
。你没有问过这个问题,但你永远不应该创建一个总是产生错误的默认类方法。在这种情况下,不要违约;如果未在实例中定义该方法,GHC将发出警告。在虚假默认情况下,用户不会收到任何警告;事情在运行时就发生了。曾经有一段尴尬的时期,不是每个Monad
都是应用程序的。你没有问过这个问题,但你永远不应该创建一个总是产生错误的默认类方法。在这种情况下,不要违约;如果未在实例中定义该方法,GHC将发出警告。在虚假默认情况下,用户不会收到任何警告;事情只是在运行时爆炸。