假设:
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库中的常见模式?
答案 0 :(得分:2)
这似乎是写出你想要的最简洁的方式(并且还表明为什么,作为一个微不足道的组合,它不直接包含在lib中)。
> :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