【问题标题】:Traversable#mapM & sequence - Necessary?Traversable#mapM & 序列 - 有必要吗?
【发布时间】:2015-12-28 03:37:46
【问题描述】:

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

【问题讨论】:

  • 有一段尴尬的时期,不是每个Monad 都是Applicative
  • 你没有问过这个问题,但你应该永远创建一个总是产生错误的默认类方法。在这种情况下不要默认;如果方法没有在实例中定义,GHC 会发出警告。使用虚假默认值,用户不会收到警告;事情只是在运行时爆炸。

标签: haskell


【解决方案1】:

正如 cmets 中所提到的,曾经有一段时间并非每个 Monad 都是 Applicative。 就在最近(在 GHC 7.10 附带的base-4.8 中)Applicative 成为Monad 的超类。你可能见过Applicative-Monad-Proposal, AMP

目前Monad of no return, MRP (email-thread) 正在开发中,这将使 Monad>>Applicative*> 相同。这最终可以说traverse = mapMsequence = sequenceA。但这是一个漫长的过程,需要时间。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-03
    • 2012-12-14
    • 1970-01-01
    • 2021-11-11
    • 2016-04-24
    • 2011-06-06
    相关资源
    最近更新 更多