Last active
December 25, 2015 06:09
-
-
Save miguel-vila/6929747 to your computer and use it in GitHub Desktop.
The setup: four types A,B, C and D, an initial value x of the type Future[Option[A]] and three functions: f1: A => Option[B] , f2: B => Future[Option[C]] and f3: C => D. How can you write a for comprehension starting with x that results in a value of the type Future[Option[D]] that would be the "composition" of the three functions? (thanks to Huw:
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
import scalaz.contrib.std.FutureInstances // Dependency: scalaz-contrib | |
import scalaz.{ Monad , OptionT } // Dependency: scalaz | |
import scala.concurrent.ExecutionContext.Implicits.global | |
import scala.concurrent.Future | |
class FutureAndOptionComposition[A, B, C, D] | |
extends FutureInstances | |
// The FutureInstances trait has a method which creates a Monad instance | |
// for Future which is used implicitly by the OptionT | |
{ | |
val x: Future[Option[A]] = ??? | |
def f1: A => Option[B] = ??? | |
def f2: B => Future[Option[C]] = ??? | |
def f3: C => D = ??? | |
val result: Future[Option[D]] = (for { | |
a <- OptionT(x) | |
b <- OptionT(Future.successful(f1(a))) // Alternatively using scalaz Option (import scalaz.std.option._) this could be rewritten as b <- OptionT( f1(a).point[Future] ) | |
c <- OptionT(f2(b)) | |
} yield f3(c)).run | |
//To make it look smoother: | |
import scala.language.implicitConversions | |
implicit def conversion[X](optt: OptionT[Future,X]): Future[Option[X]] = optt.run | |
val result2: Future[Option[D]] = for { | |
a <- OptionT(x) | |
b <- OptionT(Future.successful(f1(a))) | |
c <- OptionT(f2(b)) | |
} yield f3(c) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment