我有用于封装列表的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
})
这似乎可以编译,但是我觉得应该比这更简单,更短。有任何改进的想法吗?
答案 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)可能是您正在寻找的抽象