Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 可遍历的#mapM&;顺序-必要吗?_Haskell - Fatal编程技术网

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将发出警告。在虚假默认情况下,用户不会收到任何警告;事情只是在运行时爆炸。