package concpar20final03 import scala.concurrent.{Await, Future} import scala.concurrent.duration.Duration import scala.concurrent.ExecutionContext.Implicits.global import scala.util.{Failure, Success} def sequence1[A](fs: List[Future[A]]): Future[List[A]] = fs match case f :: fs => for x <- f xs <- sequence1(fs) yield x :: xs case Nil => Future.successful(Nil) def sequence2[A](fs: List[Future[A]]): Future[List[A]] = fs match case f :: fs => f.flatMap(x => sequence2(fs).map(xs => x :: xs)) case Nil => Future.successful(Nil) def sequence3[A](fs: List[Future[A]]): Future[List[A]] = fs match case f :: fs => f.transformWith { case Failure(e) => Future.failed(e) case Success(value) => sequence3(fs).transform { case res: Failure[List[A]] => res case Success(values) => Success(value :: values) } } case Nil => Future.successful(Nil) def sequence4[A](fs: List[Future[A]]): Future[List[A]] = fs match case f :: fs => val fsFuture: Future[List[A]] = sequence4(fs) f.zip(fsFuture).map((fValue, fsValue) => fValue :: fsValue) case Nil => Future.successful(Nil) @main def concpar20final03 = val xs = List(Future { 1 }, Future { 2 }, Future { 3 }) val ys = List(Future { 1 }, Future.failed(Error("BOOM")), Future { 3 }) println(Await.result(sequence1(xs), Duration.Inf)) // println(Await.result(sequence1(xs), Duration.Inf)) // Throws exception println(Await.result(sequence2(xs), Duration.Inf)) // println(Await.result(sequence2(ys), Duration.Inf)) // Throws exception println(Await.result(sequence3(xs), Duration.Inf)) // println(Await.result(sequence3(ys), Duration.Inf)) // Throws exception println(Await.result(sequence4(xs), Duration.Inf)) // println(Await.result(sequence4(ys), Duration.Inf)) // Throws exception