Note that there are some explanatory texts on larger screens.

plurals
  1. POFuture[Option] in Scala for-comprehensions
    primarykey
    data
    text
    <p>I have two functions which return Futures. I'm trying to feed a modified result from first function into the other using a for-yield comprehension. </p> <p>This approach works:</p> <pre><code> val schoolFuture = for { ud &lt;- userStore.getUserDetails(user.userId) sid = ud.right.toOption.flatMap(_.schoolId) s &lt;- schoolStore.getSchool(sid.get) if sid.isDefined } yield s </code></pre> <p>However I'm not happy with having the "if" in there, it seems that I should be able to use a map instead. </p> <p>But when I try with a map:</p> <pre><code> val schoolFuture: Future[Option[School]] = for { ud &lt;- userStore.getUserDetails(user.userId) sid = ud.right.toOption.flatMap(_.schoolId) s &lt;- sid.map(schoolStore.getSchool(_)) } yield s </code></pre> <p>I get a compile error:</p> <pre><code>[error] found : Option[scala.concurrent.Future[Option[School]]] [error] required: scala.concurrent.Future[Option[School]] [error] s &lt;- sid.map(schoolStore.getSchool(_)) </code></pre> <p>I've played around with a few variations, but haven't found anything attractive that works. Can anyone suggest a nicer comprehension and/or explain what's wrong with my 2nd example?</p> <p>Here is a minimal but complete runnable example with Scala 2.10:</p> <pre><code>import concurrent.{Future, Promise} case class User(userId: Int) case class UserDetails(userId: Int, schoolId: Option[Int]) case class School(schoolId: Int, name: String) trait Error class UserStore { def getUserDetails(userId: Int): Future[Either[Error, UserDetails]] = Promise.successful(Right(UserDetails(1, Some(1)))).future } class SchoolStore { def getSchool(schoolId: Int): Future[Option[School]] = Promise.successful(Option(School(1, "Big School"))).future } object Demo { import concurrent.ExecutionContext.Implicits.global val userStore = new UserStore val schoolStore = new SchoolStore val user = User(1) val schoolFuture: Future[Option[School]] = for { ud &lt;- userStore.getUserDetails(user.userId) sid = ud.right.toOption.flatMap(_.schoolId) s &lt;- sid.map(schoolStore.getSchool(_)) } yield s } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload