I love Scala's for comprehensions! I would love them even more if I could find a way to map over the right-hand side result before assigning it to a value. Say I have the following code:
case class Person(name: String)
def getPersonById(id: Long): Future[Option[Person]] = ???
case class Dog(color: String)
def getDogById(id: Long): Future[Dog] = ???
def addStringToFile(name: Seq[String]): Future[Unit] = ???
val id: Long = ???
for {
person <- getPersonById(id)
name = person.map(_.name)
dog <- getDogById(id)
color = dog.color
_ <- addNamesToFile(Seq(name, color).flatten)
} yield name
I don't actually need person or dog as an intermediate value; the are only valuable to the extent that I can extract a property from them on the very next line. Ideally what I'd like to do would look something vaguely like this:
for {
name <- getPersonById(id))>>.map(_.name)
color <- getDogById(id))>>.color
_ <- addNamesToFile(Seq(name, color).flatten)
} yield name
But obviously this isn't valid Scala. Outside of a for-comprenshion I would do:
val name = getPersonById(id).map(_.map(_.name))
val color = getDogById(id).map(_.color)
But the neat thing about the for-comprehension is that I don't need to explicitly perform the outer .map, and the "Future" part is hidden away.
Is it possible to map over the result of a right-hand side expression in a for-comprehension before assigning it to a value?
Note that you can actually write exactly that by simply replacing your cryptic
)>>.withmap:)The only difference between this and what you wrote is
.mapvs.>>If you like your syntax more for some reason, make an implicit:Now, you can do
This is almost exactly what you had - just a couple of braces and an underscore added ...