(Monad m, Monoid a, Foldable t) => t (m a) 的序列实例?

An instance of sequence for (Monad m, Monoid a, Foldable t) => t (m a)?

鉴于:

sequence :: (Monad m, Traversable t) => t (m a) -> m (t a)
sequence_ :: (Monad m, Foldable t) => t (m a) -> m ()

想要:

sequenceMonoid :: (Monad m, Foldable t, Monoid t1) => t (m t1) -> m t1
sequenceMonoid = foldr (\m m' -> do { x <- m; xs <- m'; return (x `mappend` xs) }) (return mempty)

为了清楚起见,仅列表版本应定义为:

sequenceMonoid :: (Monad m, Monoid t1) => [m t1] -> m t1
sequenceMonoid x = mconcat <$> (sequence x)

用法示例:

sequenceMonoid [Just [1,2],Just [3,4]]
Just [1,2,3,4]

这个定义正确吗?如果是的话,我会期望这是一个常见的模式,已经存在于现有的 Monoid 库中的某个地方?

这似乎是编写您想要的内容的最简洁的方式(并且还说明了为什么作为一个简单的组合,它没有直接包含在库中)。

> :t fmap fold . sequence
fmap fold . sequence :: (Monad f, Traversable t, Monoid b) => t (f b) -> f b

您可以将 sequence 概括为 sequenceA 以获得更一般的内容。

> :t fmap fold . sequenceA
fmap fold . sequenceA :: (Applicative f, Traversable t, Monoid b) => t (f b) -> f b