Created
October 11, 2013 20:43
-
-
Save sam/6941737 to your computer and use it in GitHub Desktop.
Makes mapping lots of futures pretty/easy.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Imagine you have a lot of futures. You don't want to make them synchronous with a for-comprehension, so you want to zip them. | |
// Unfortunately you'll get nested tuples from that, and if you have more than two, that gets ugly quick. | |
// ScalaZ has a solution with the |@| operator, but it's more general and seems to really torture the compiler. | |
// This is an alternative for this specific scenario (zip several async Futures together and map them), and is much faster | |
// (in IntelliJ at least). | |
import my.api | |
import TupleFutureUnzip._ | |
(ChanneledPresenter.tree, api.photos.all) unzip(new PhotosPresenter(_, _)) | |
// That's just two arguments, but doesn't matter how many (I've provided the first 8 at least for you). | |
// You can also pattern-match since it's just a map: | |
(ChanneledPresenter.tree, api.pages.getByRoute(route)) unzip { | |
case (tree, Some(page)) => Some(new PagePresenter(tree, page)) | |
case _ => None | |
} | |
// Hope you find this helpful! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package util | |
import scala.concurrent.{ExecutionContext, Future} | |
object TupleFutureUnzip { | |
type Tuple1Futures[A] = Tuple1[Future[A]] | |
type Tuple2Futures[A,B] = Tuple2[Future[A],Future[B]] | |
type Tuple3Futures[A,B,C] = Tuple3[Future[A],Future[B],Future[C]] | |
type Tuple4Futures[A,B,C,D] = Tuple4[Future[A],Future[B],Future[C],Future[D]] | |
type Tuple5Futures[A,B,C,D,E] = Tuple5[Future[A],Future[B],Future[C],Future[D],Future[E]] | |
type Tuple6Futures[A,B,C,D,E,F] = Tuple6[Future[A],Future[B],Future[C],Future[D],Future[E],Future[F]] | |
type Tuple7Futures[A,B,C,D,E,F,G] = Tuple7[Future[A],Future[B],Future[C],Future[D],Future[E],Future[F],Future[G]] | |
type Tuple8Futures[A,B,C,D,E,F,G,H] = Tuple8[Future[A],Future[B],Future[C],Future[D],Future[E],Future[F],Future[G],Future[H]] | |
implicit class Tuple1Unzip[A](val self: Tuple1Futures[A]) extends AnyVal { | |
def unzip[R](fun: Function1[A,R])(implicit ec: ExecutionContext): Future[R] = { | |
self._1 map { fun(_) } | |
} | |
} | |
implicit class Tuple2Unzip[A,B](val self: Tuple2Futures[A,B]) extends AnyVal { | |
def unzip[R](fun: Function2[A,B,R])(implicit ec: ExecutionContext): Future[R] = { | |
self._1 zip self._2 map { | |
case (a, b) => fun(a,b) | |
} | |
} | |
} | |
implicit class Tuple3Unzip[A,B,C](val self: Tuple3Futures[A,B,C]) extends AnyVal { | |
def unzip[R](fun: Function3[A,B,C,R])(implicit ec: ExecutionContext): Future[R] = { | |
self._1 zip self._2 zip self._3 map { | |
case ((a, b), c) => fun(a,b,c) | |
} | |
} | |
} | |
implicit class Tuple4Unzip[A,B,C,D](val self: Tuple4Futures[A,B,C,D]) extends AnyVal { | |
def unzip[R](fun: Function4[A,B,C,D,R])(implicit ec: ExecutionContext): Future[R] = { | |
self._1 zip self._2 zip self._3 zip self._4 map { | |
case (((a, b), c), d) => fun(a,b,c,d) | |
} | |
} | |
} | |
implicit class Tuple5Unzip[A,B,C,D,E](val self: Tuple5Futures[A,B,C,D,E]) extends AnyVal { | |
def unzip[R](fun: Function5[A,B,C,D,E,R])(implicit ec: ExecutionContext): Future[R] = { | |
self._1 zip self._2 zip self._3 zip self._4 zip self._5 map { | |
case ((((a, b), c), d), e) => fun(a,b,c,d,e) | |
} | |
} | |
} | |
implicit class Tuple6Unzip[A,B,C,D,E,F](val self: Tuple6Futures[A,B,C,D,E,F]) extends AnyVal { | |
def unzip[R](fun: Function6[A,B,C,D,E,F,R])(implicit ec: ExecutionContext): Future[R] = { | |
self._1 zip self._2 zip self._3 zip self._4 zip self._5 zip self._6 map { | |
case (((((a, b), c), d), e), f) => fun(a,b,c,d,e,f) | |
} | |
} | |
} | |
implicit class Tuple7Unzip[A,B,C,D,E,F,G](val self: Tuple7Futures[A,B,C,D,E,F,G]) extends AnyVal { | |
def unzip[R](fun: Function7[A,B,C,D,E,F,G,R])(implicit ec: ExecutionContext): Future[R] = { | |
self._1 zip self._2 zip self._3 zip self._4 zip self._5 zip self._6 zip self._7 map { | |
case ((((((a, b), c), d), e), f), g) => fun(a,b,c,d,e,f,g) | |
} | |
} | |
} | |
implicit class Tuple8Unzip[A,B,C,D,E,F,G,H](val self: Tuple8Futures[A,B,C,D,E,F,G,H]) extends AnyVal { | |
def unzip[R](fun: Function8[A,B,C,D,E,F,G,H,R])(implicit ec: ExecutionContext): Future[R] = { | |
self._1 zip self._2 zip self._3 zip self._4 zip self._5 zip self._6 zip self._7 zip self._8 map { | |
case (((((((a, b), c), d), e), f), g), h) => fun(a,b,c,d,e,f,g,h) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment