Reputation: 31586
I have written this code
def m1(x: Int) = Future { if (x % 2 == 0) Some(x) else None }
def m2(x: Int) = Future { if (x % 2 != 0) Some(x) else None }
for {
x <- Some(3)
x1 <- m1(x)
x2 <- m2(x)
} yield x1 orElse x2
My objective is that the code should first open the future of m1 and if that has a some, then use that value. otherwise, it should open the future of m2 and use that value.
But it keeps getting a compile time error
<console>:26: error: type mismatch;
found : scala.concurrent.Future[Option[Int]]
required: Option[?]
x1 : Option[Int] <- m1(x)
^
Upvotes: 2
Views: 2287
Reputation: 2480
The problem is that in the for comprehension the first element obtained from the generator - x
- is an Option
, while the others are Future
s. Unfortunately Scala doesn't support having different generator types in the same for comprehension and you would need a monad transformer to achieve this.
The simple way is just to wrap the Option in a Future:
for {
Some(x) <- Future.successful(Some(3))
x1 <- m1(x)
x2 <- m2(x)
} yield x1 orElse x2
I hope that helps.
Upvotes: 4
Reputation: 755
You are receiving this error because for expression is being translated to chain of flatMap
, map
, filter
, withFilter
and foreach
method calls. Generally speaking expression:
for {
x <- X
y <- Y
} yield yourCode(x, y)
Is translated to code somewhat similar to the following:
X.flatMap(x => Y.map(y => yourFunc(x, y))
I simplified it a bit, in reality partial function are used but general idea remains the same.
Option has the following signature of flatMap
method:
def flatMap[B](f : A => Option[B]): Option[B]
def flatMap[B](f : A => GenTraversableOnce[B]): Option[B]
Future is not an Option instance nor GenTraversableOnce so it is impossible to use for comprehension for it, your code after transformation looks similar to the following:
Some(3).flatMap(x => m1(x).flatMap(x1 => m2(x1).map(x2 => x1 orElse x2)))
Type of m1(x).flatMap(x1 => m2(x1).map(x2 => x1 orElse x2))
is Future[Option[Int]]
which does not conform to the flatMap
signature.
I hope my answer will help understand for comprehension.
Upvotes: 1