I'm reading about scalaz and noticed that we can make a list of Applicative
s to be an Applicative
of 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)) {_ :: _}
}
The question is can we do the opposite? Can we transform F[List[A]]
to List[F[A]]
?
This is possible if the F
in question is Traversable
. The code you're showing is specialized for List
, but in fact it holds for all Traversable
functors.
This means, that for every F
that's Traversable
and any G
that's Applicative
, we can go from F[G[A]]
to G[F[A]]
with sequence
.
List
also has an Applicative
, so we can use it as our G
, whereas in your example List
was used as the F
, the Traversable
functor.
An example where what you're asking works could be Option
. Here's the original direction:
val x: List[Option[Int]] = ...
val y: Option[List[Int]] = x.sequence
and the other direction:
val a: Option[List[Int]] = ...
val b: List[Option[Int]] = a.sequence
We could also write another function specializing to List
:
def sequenceT[F[_]: Traverse, A](list: F[List[A]]): List[F[A]] = ...