and scala akka

and - En futuros de Scala Akka, ¿cuál es la diferencia entre map y flatMap?



java 8 optional map vs flatmap (3)

en el mapa normal de Scala y flatMap son diferentes en que flatMap devolverá un iterable de los datos aplastados en una lista. Sin embargo, en la documentación de Akka, el mapa y el mapa plano parecen hacer algo diferente.

http://akka.io/docs/akka/1.1/scala/futures.html

Dice: "Normalmente, esto funciona bastante bien, ya que significa que hay muy poca sobrecarga para ejecutar una función rápida. Si existe la posibilidad de que la función requiera una cantidad de tiempo no trivial para procesar, es mejor hacer esto simultáneamente. y para eso usamos flatMap: "

val f1 = Future { "Hello" + "World" } val f2 = f1 flatMap {x => Future(x.length) } val result = f2.get()

¿Puede alguien explicar por favor cuál es la diferencia entre map y flatMap aquí en Akka Futures?


¿Puede alguien explicar por favor cuál es la diferencia entre map y flatMap aquí en Akka Futures?

El tipo, básicamente:

flatMap[A](f: T => Future[A]): Future[A] map[A](f: T => A): Future[A]


En Scala "normal" (como dices), el mapa y el mapa plano no tienen nada que ver con las listas (ver opción, por ejemplo).

Alexey te dio la respuesta correcta. Ahora, si quiere saber por qué necesitamos ambos, permite la sintaxis agradable al componer futuros. Dado algo como:

val future3 = for( x <- future1; y <- future2 ) yield ( x + y )

El compilador lo reescribe como:

val future3 = future1.flatMap( x => future2.map( y => x+y ) )

Si sigue la firma del método, debería ver que la expresión devolverá algo del tipo Future[A] .

Supongamos que ahora solo se utilizó el mapa, el compilador podría haber hecho algo como:

val future3 = future1.map( x => future2.map( y => x+y ) )

Sin embargo, el resultado debería haber sido de tipo Future[Future[A]] . Es por eso que debes aplanarlo.

Para conocer el concepto subyacente, esta es una de las mejores introducciones que he leído:

http://www.codecommit.com/blog/ruby/monads-are-not-metaphors


Estoy pegando la implementación de los dos métodos aquí. la diferencia en términos ingleses está abajo y devuelve el resultado de la función como el nuevo futuro

/** Creates a new future by applying a function to the successful result of * this future. If this future is completed with an exception then the new * future will also contain this exception. * * $forComprehensionExamples */ def map[S](f: T => S)(implicit executor: ExecutionContext): Future[S] = { // transform(f, identity) val p = Promise[S]() onComplete { v => p complete (v map f) } p.future } /** Creates a new future by applying a function to the successful result of * this future, and returns the result of the function as the new future. * If this future is completed with an exception then the new future will * also contain this exception. * * $forComprehensionExamples */ def flatMap[S](f: T => Future[S])(implicit executor: ExecutionContext): Future[S] = { import impl.Promise.DefaultPromise val p = new DefaultPromise[S]() onComplete { case f: Failure[_] => p complete f.asInstanceOf[Failure[S]] case Success(v) => try f(v) match { // If possible, link DefaultPromises to avoid space leaks case dp: DefaultPromise[_] => dp.asInstanceOf[DefaultPromise[S]].linkRootOf(p) case fut => fut.onComplete(p.complete)(internalExecutor) } catch { case NonFatal(t) => p failure t } } p.future }

Desde la implementación, la diferencia es que flatMap en realidad llama a la función con el resultado cuando se completa la promesa.

case Success(v) => try f(v) match

Para un excelente artículo, lee: http // danielwestheide.com / blog / 2013/01/16 / the-neophytes-guide-to-scala-part-9-promises-and-futures-in-practice.html