Scala 如何在列表[F[G[A]]上运行序列以获得F[G[List[A]]

Scala 如何在列表[F[G[A]]上运行序列以获得F[G[List[A]],scala,scalaz,Scala,Scalaz,是否可以将List[F[G[a]]]转换为F[G[List[a]]]] 我可以通过以下方式在Scalaz中执行此操作: val x: List[Future[Option[Int]]] = ??? val transformed: Future[Option[List[Int]]] = x.sequenceU.map(_.sequenceU) 我只是想知道是否有更好的方法来实现这一点,而不是使用monad转换器?我确实尝试过,但运气不太好。如果您想避免嵌套排序,Monad transforme

是否可以将
List[F[G[a]]]
转换为
F[G[List[a]]]]

我可以通过以下方式在Scalaz中执行此操作:

val x: List[Future[Option[Int]]] = ???
val transformed: Future[Option[List[Int]]] = x.sequenceU.map(_.sequenceU)

我只是想知道是否有更好的方法来实现这一点,而不是使用monad转换器?我确实尝试过,但运气不太好。

如果您想避免嵌套排序,Monad transformers是一种不错的选择。在这种情况下,您需要一个
选项[Future,A]
(相当于
未来[Option[A]]]
):

然后:

scala> sequencedXs.foreach(println)
Some(List(1, 2))

scala> sequencedYs.foreach(println)
None
scala> future.foreach(println)
Some(List(1, 2))

正如预期的那样。

我意识到,虽然monad转换器在这里很好,但我可以利用应用程序构成的优势:

def transform[F[_], G[_], A](list: List[F[G[A]]])(implicit af: Applicative[F], ao: Applicative[G]): F[G[List[A]]] = {
  type λ[α] = F[G[α]]
  implicit val applicative: Applicative[λ] = af compose ao
  list.sequence[λ, A]
}
val lfo:    List[Future[Option[Int]]] = List(Future(1.some), Future(2.some))
val future: Future[Option[List[Int]]] = transform(lfo)
然后:

scala> sequencedXs.foreach(println)
Some(List(1, 2))

scala> sequencedYs.foreach(println)
None
scala> future.foreach(println)
Some(List(1, 2))

当你想起来的时候,这是很明显的,真的:)谢谢。当然,这是拉尔斯当时建议的,但当时它并不适合我。