如果M是单声道,如何正确地将List [M [List [A]]]合并为M [List [A]]?

时间:2018-07-03 12:55:27

标签: scala functional-programming monads applicative scala-cats

我有用于封装列表的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
})

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

2 个答案:

答案 0 :(得分:2)

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

List[M[List[A]]]

您应该可以将sequence中的Traverse[List]中的Applicative[M]M[List[List[A]]] 一起使用

map

然后使用Functor[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

对于{{1}}。

答案 1 :(得分:0)

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