В флагов Scala Akka, в чем разница между map и flatMap?

в нормальном Scala карте и flatMap отличаются тем, что flatMap вернет итерабельность данных, сплющенных в список. Однако в документации Akka карта и flatMap, похоже, делают что-то другое?

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

В нем говорится: "Обычно это работает очень хорошо, так как это означает, что для быстрой работы очень мало накладных расходов. Если есть возможность того, что функция требует нетривиального количества времени для обработки, было бы лучше иметь это выполняются одновременно, и для этого мы используем flatMap:"

val f1 = Future {
  "Hello" + "World"
}

val f2 = f1 flatMap {x =>
  Future(x.length)
}

val result = f2.get()

Может кто-нибудь, пожалуйста, объясните, в чем разница между map и flatMap здесь на фьючерсах Akka?

Ответ 1

В "нормальном" Scala (как вы говорите) карта и flatMap не имеют ничего общего с списками (например, проверьте параметр).

Алексей дал вам правильный ответ. Теперь, если вы хотите знать, почему нам нужны оба, он позволяет использовать хороший синтаксис for при составлении фьючерсов. Учитывая что-то вроде:

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

Компилятор переписывает его как:

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

Если вы следуете сигнатуре метода, вы должны увидеть, что выражение вернет что-то типа Future[A].

Предположим, что теперь используется только карта, компилятор мог бы сделать что-то вроде:

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

Однако результат был бы типа Future[Future[A]]. Вот почему вам нужно сгладить его.

Чтобы узнать о концепции позади, вот одно лучшее введение, которое я прочитал:

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

Ответ 2

Может кто-нибудь, пожалуйста, объясните, в чем разница между map и flatMap здесь на фьючерсах Akka?

Тип, в основном:

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

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

Ответ 3

Я вставляю реализацию двух методов здесь. разница в английских условиях ниже и возвращает результат функции как новое будущее

         /** 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
   }

От реализации разница заключается в том, что flatMap фактически вызывает функцию с результатом, когда обещание завершается.

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

Для большой статьи читайте: http//danielwestheide.com/blog/2013/01/16/the-neophytes-guide-to- scala -part-9- promises -and-futures-in- practice.html