Skip to content

Instantly share code, notes, and snippets.

@drstevens
Created January 21, 2013 21:28
Show Gist options
  • Save drstevens/4589599 to your computer and use it in GitHub Desktop.
Save drstevens/4589599 to your computer and use it in GitHub Desktop.
Define Apply[Future] in order to sequence. Written for Akka 1.3.1 (old, I know) and Scalaz 6.0.4. I imagine similar could be written for Akka 2.1.x and Scalaz 7. I've used this in many places so far without issue, but I've only used it for sequencing through something like `Validation[S, Future[Validation[S, Future[B]]]`. If I'm breaking some la…
object FuturePimps {
/**
* Use this instead of new AlreadyCompletedFuture[T] to prevent accidental use of default Akka timeout
**/
def alreadyCompletedFuture[T](v: T)(implicit timeout: Timeout): AlreadyCompletedFuture[T] =
new AlreadyCompletedFuture[T](Right(v), timeout.duration.toMillis)
class FutureFuture[T](f: () => Future[Future[T]]) {
def flatten: Future[T] = f().flatMap(identity)
}
implicit def `pimpMyFuture^2`[T](f: => Future[Future[T]]) = new FutureFuture(() => f)
object TypeClasses {
implicit def FutureBind = new Bind[Future] {
def bind[A, B](a: Future[A], f: A => Future[B]) = a flatMap f
}
implicit def FutureFunctor: Functor[Future] = new Functor[Future] {
def fmap[A, B](r: Future[A], f: A => B) = r map f
}
/**
* NOTE: In order to use this, a timeout must be implicitly in scope at call site!!!
* If no timeout is in scope, type checker will likely fail with error about missing Applicative
*/
implicit def FuturePure(implicit timeout: Timeout): Pure[Future] = new Pure[Future] {
def pure[A](a: => A) = alreadyCompletedFuture(a)
}
implicit def FutureApply[S]: Apply[Future] = FunctorBindApply[Future]
}
}
import FuturePimps._
import FuturePimps.TypeClasses._
implicit val timeout: ActorTimeout = Duration(10, TimeUnit.SECONDS)
val expectedSuccess = 5
val successOfFuture: Validation[String, Future[Int]] = alreadyCompletedFuture(5).success
val futureOfSuccess = successOfFuture.sequence
futureOfSuccess.get assert_=== expectedSuccess.success
val expectedFailure = "Failed!!!"
val failureOfFuture: Validation[String, Future[Int]] = expectedFailure.fail
val futureOfFailure = failureOfFuture.sequence
futureOfFailure.get assert_=== expectedFailure.fail
val expectedOptionValue = 5
val optionOfFuture: Option[Future[Int]] = alreadyCompletedFuture(5).some
val futureOfOption = optionOfFuture.sequence
futureOfOption.get assert_=== expectedOptionValue.some
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment