-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfor_comprehensions.scala
89 lines (65 loc) · 2.72 KB
/
for_comprehensions.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
///////////////////////////////////////////////////////////////////////
// assign new values during for-comprehension //
val a1, b1, c1 = Option(1)
for {
i <- a1
j <- b1
ij = i + j
k <- c1
} yield ij + k //
///////////////////////////////////////////////////////////////////////
// Either, short-circuit with information (as opposed to Option) //
val a2, b2 = Right(1)
val c2: Either[String, Int] = Left("sorry, no c")
for {
i <- a2
j <- b2
k <- c2
} yield i + j + k
// > scala.util.Either[String,Int] = Left(sorry, no c) //
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Future, short-circuit with future //
import scala.concurrent._
import ExecutionContext.Implicits.global
for {
i <- Future.failed[Int](new Throwable)
j <- Future { println("hello") ; 1 }
} yield i + j
// > scala.concurrent.Future[Int] = Future(Failure(java.lang.Throwable))
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Combine Future with Option using Scalaz' OptionT //
import scalaz._, Scalaz._
def getA: Future[Option[Int]] = Future(Some(10))
def getB: Future[Option[Int]] = Future(Some(20))
def getC: Future[Int] = Future(30)
def getD: Option[Int] = Some(1)
val result = for {
a <- OptionT(getA)
b <- OptionT(getB)
c <- getC.liftM[OptionT]
d <- OptionT(getD.pure[Future])
} yield a * b + c + d
// > result: scalaz.OptionT[scala.concurrent.Future,Int] = OptionT(Future(<not completed>))
// and then get the result with run
result.run
// scala.concurrent.Future[Option[Int]] = Future(Success(Some(200))) //
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Same as previous but cleaned up using the Scalaz DSL //
// (the |> (thrush) operator applies the function on the right to //
// the value on the left) //
def liftFutureOption[A](f: Future[Option[A]]) = OptionT(f)
def liftFuture[A](f: Future[A]): OptionT[Future, A] = f.liftM[OptionT]
def liftOption[A](o: Option[A]) = OptionT(o.pure[Future])
def lift[A](a: A): OptionT[Future, A] = liftOption(Option(a))
val result = for {
a <- getA |> liftFutureOption
b <- getB |> liftFutureOption
c <- getC |> liftFuture
d <- getD |> liftOption
e <- 10 |> lift
} yield e * (a * b) / (c * d)
// //
///////////////////////////////////////////////////////////////////////