如果 M 是 monad,如何将 List[M[List[A]]] 正确组合到 M[List[A]] 中?

How to properly combine List[M[List[A]]] into M[List[A]] if M is a monad?

我有包装列表的单子。我想将这些 monad 组合起来形成一个 monad 来包装所有列表的串联。

M[List[A]] + M[List[A]] ==> M[List[A]]

为了实现这一点,我做了以下 (伪代码)

(1 to 10).foldLeft(Option(List(0)))((accumulator, i) => {
  for {
    prev <- accumulator
    more <- Option(List(i))
  } yield prev ++ more
})

这似乎可以编译,但我觉得它应该比这更简单 更短。有什么改进的想法吗?

我认为 semigroup(或 SemigroupK)可能是您正在寻找的抽象

有一个 Traverse[List] 的实例。 每个 Monad[M] 都是 Applicative[M] 的特例。因此,如果您有

List[M[List[A]]]

您应该可以在 Traverse[List] 中使用 sequenceApplicative[M] 来首先将其转换为

M[List[List[A]]]

然后用mapFunctor[M]flatten就变成了

M[List[A]]

类似

val lists: List[Option[List[A]]] = ???
val optLists: Option[List[List[A]]] = Traverse[List].sequence(lists)
val optList: Option[List[A]] = optLists.map(_.flatten)

Option的情况下。