I'm reading about scalaz并注意到我们可以列出Applicative
s是Applicative
的List
。
def sequenceA[F[_]: Applicative, A](list: List[F[A]]): F[List[A]] = list match {
case Nil => (Nil: List[A]).point[F]
case x :: xs => (x |@| sequenceA(xs)) {_ :: _}
}
问题是我们可以做相反的事吗?我们可以将F[List[A]]
变换为List[F[A]]
吗?
如果F
是Traversable
,这是可能的。您展示的代码专门用于List
,但实际上它适用于所有Traversable
仿函数。
这意味着,对于F
和Traversable
的任何G
的每个Applicative
,我们可以用F[G[A]]
从G[F[A]]
到sequence
。
List
也有一个Applicative
,所以我们可以用它作为我们的G
,而在你的例子中List
被用作F
,Traversable
仿函数。
你要问的工作的例子可能是Option
。这是最初的方向:
val x: List[Option[Int]] = ...
val y: Option[List[Int]] = x.sequence
和另一个方向:
val a: Option[List[Int]] = ...
val b: List[Option[Int]] = a.sequence
我们还可以编写另一个专门针对List
的函数:
def sequenceT[F[_]: Traverse, A](list: F[List[A]]): List[F[A]] = ...