【发布时间】: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'
如果我对 mapM 和 sequence' 的实现是正确的,并且由于每个 Monad 都是 Applicative:
λ: :i Monad
class Applicative m => Monad (m :: * -> *) where
...
那么我不清楚为什么mapM 和sequence' 甚至是必要的。他们为什么会这样?
附: - 感谢 haoformayor 帮助我解决问题,感谢 sequenceA。
【问题讨论】:
-
有一段尴尬的时期,不是每个
Monad都是Applicative。 -
你没有问过这个问题,但你应该永远创建一个总是产生错误的默认类方法。在这种情况下不要默认;如果方法没有在实例中定义,GHC 会发出警告。使用虚假默认值,用户不会收到警告;事情只是在运行时爆炸。
标签: haskell