Hbf
Hbf

Reputation: 3114

Optimisation of Scala's for-comprehension (identity map)

How can I avoid a map(identity) in Scala for-comprehensions?

For example, consider:

import scala.concurrent._
import scala.concurrent.duration._

object Test extends App {
  implicit val executorContext = ExecutionContext.global
  val future = Future.successful { 1 }
  val result = for (
    value <- future;
    b <- Future { value * 2 }
  ) yield b
  println(Await.result(result, 60 seconds))
}

IIUC, the for-comprehension translates to something like

future.flatMap(value => Future { value * 2 }).map(identity)

Can I avoid the trailing map(identity) in some way? Or does/can/could Scala optimise it away? (I suppose it cannot as it is not clear whether map has any side effects, right?)

P.S. I know that in this particular example, things can be improved. I am wondering about the general case, where for instance Future { value * 2} is a call f(value) to a function f returning a future.

Upvotes: 1

Views: 436

Answers (1)

Francois G
Francois G

Reputation: 11985

It's an anti-pattern to create your own Future just to operate applicatively inside one. You can instead:

  • future.map() and finally get your result with onSuccess (this is the simplest model)
  • if you are dead set on comprehensions, yield Future { value * 2 } and then get your result ... (though this doesn't solve the spurious Future creation problem)
  • transform your Future and then get your result ...
  • collect on your future and then map(f) on results

Depending on your context and computation model, one or another of these solutions might more appropriate : you seem to be presenting a specific case of a general situation, but it's unclear if the general situation should involve iterating over Futures, chaining transformations in one Future, or something else entirely.

Upvotes: 2

Related Questions