(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
鉴于:
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