Created
March 14, 2015 01:50
-
-
Save chenharryhua/0d914addaaf32dabdf42 to your computer and use it in GitHub Desktop.
This file contains 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 futurable | |
import scala.concurrent.Future | |
import concurrent.ExecutionContext.Implicits.global | |
trait Futurable[In] { | |
type Out | |
def apply(in: In): Future[Out] | |
} | |
case object NoneException extends Exception | |
trait LowerPriorityFuturableOption { | |
implicit def futureOption[T] = new Futurable[Option[T]] { | |
type Out = T | |
def apply(in: Option[T]): Future[T] = { | |
in match { | |
case None => Future.failed(NoneException) | |
case Some(x) => Future.successful(x) | |
} | |
} | |
} | |
} | |
trait FuturableOption extends LowerPriorityFuturableOption { | |
implicit def futureOption2[T](implicit fo: Futurable[Option[T]]) = | |
new Futurable[Option[Option[T]]] { | |
type Out = fo.Out | |
def apply(in: Option[Option[T]]) = fo(in.flatten) | |
} | |
} | |
trait LowerPriorityFuturableFuture { | |
implicit def futureFuture[T] = new Futurable[Future[T]] { | |
type Out = T | |
def apply(in: Future[T]): Future[T] = in | |
} | |
} | |
trait FuturableFuture extends LowerPriorityFuturableFuture { | |
implicit def futureFuture2[T](implicit fuf: Futurable[Future[T]]) = | |
new Futurable[Future[Future[T]]] { | |
type Out = fuf.Out | |
def apply(in: Future[Future[T]]) = fuf(for { f2 <- in; f <- f2 } yield f) | |
} | |
} | |
object Futurable | |
extends FuturableOption | |
with FuturableFuture { | |
implicit def futureOptionIso[T](implicit fo: Futurable[Option[T]]) = | |
new Futurable[Future[Option[T]]] { | |
type Out = fo.Out | |
def apply(in: Future[Option[T]]) = in.flatMap { x => fo(x) } | |
} | |
implicit def optionFutureIso[T](implicit fuf: Futurable[Future[T]]) = | |
new Futurable[Option[Future[T]]] { | |
type Out = fuf.Out | |
def apply(in: Option[Future[T]]) = { | |
val f = in match { | |
case Some(x) => x | |
case None => Future.failed(NoneException) | |
} | |
fuf(f) | |
} | |
} | |
} | |
object FuturableSyntax { | |
implicit class FOSyntax[T, O](a: T)(implicit val f: Futurable[T] { type Out = O }) { | |
def toFuture = f(a) | |
} | |
} | |
object MyTest { | |
import FuturableSyntax._ | |
val oooo: Option[Option[Option[Option[Int]]]] = ??? | |
val ooooi: Future[Int] = oooo.toFuture | |
val ffff: Future[Future[Future[Future[Int]]]] = ??? | |
val ffffi: Future[Int] = ffff.toFuture | |
val ooofff: Option[Option[Option[Future[Future[Future[Int]]]]]] = ??? | |
val ooofffi: Future[Int] = ooofff.toFuture | |
val fffooo: Future[Future[Future[Option[Option[Option[Int]]]]]] = ??? | |
val fffoooi: Future[Int] = fffooo.toFuture | |
val ofooffo: Option[Future[Option[Option[Future[Future[Option[Int]]]]]]] = ??? | |
val ofooffoi: Future[Int] = ofooffo.toFuture | |
val ofoofooof: Option[Future[Option[Option[Future[Option[Option[Option[Future[Int]]]]]]]]] = ??? | |
val ofoofooofi: Future[Int] = ofoofooof.toFuture | |
val foffofffo: Future[Option[Future[Future[Option[Future[Future[Future[Option[Int]]]]]]]]] = ??? | |
val foffofffoi: Future[Int] = foffofffo.toFuture | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment