Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run sequence over List[F[G[A]]] to get F[G[List[A]]]

Tags:

scala

scalaz

Is it possible to transform a List[F[G[A]]] into F[G[List[A]]] nicely?

I can do this in Scalaz the following way:

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

I'm just wondering if there's a nicer way to do this rather than .sequenceU.map(_.sequenceU) Perhaps using a monad transformer? I did attempt this, without much luck.

like image 748
Noel M Avatar asked Oct 02 '14 14:10

Noel M


People also ask

How do you return a sequence of numbers in Python?

Python range() function. The Python range() function returns the sequence of the given number between the given range. The most common use of it is to iterate sequence type (Python range() List, string, etc. ) with for and while loop using Python.

Which function produces list of a sequence?

range () function is used to produce a list of sequences of integer numbers by default.

Which function is used to generate sequences in R?

seq() function in R Language is used to create a sequence of elements in a Vector.

What is the built in function that returns the length of a sequence?

The built-in len function returns the length of a sequence.


1 Answers

Monad transformers are the way to go if you want to avoid the nested sequencing. In this case you want an OptionT[Future, A] (which is equivalent to Future[Option[A]]):

import scalaz._, Scalaz._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

val xs = List(OptionT(Future(some(1))), OptionT(Future(some(2))))
val ys = OptionT(Future(none[Int])) :: xs

val sequencedXs: Future[Option[List[Int]]] = xs.sequenceU.run
val sequencedYs: Future[Option[List[Int]]] = ys.sequenceU.run

And then:

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

scala> sequencedYs.foreach(println)
None

As expected.

like image 91
Travis Brown Avatar answered Sep 30 '22 05:09

Travis Brown