web-dev-qa-db-ja.com

Scala Akka先物、mapとflatMapの違いは何ですか?

通常の場合Scala mapとflatMapは、flatMapがフラット化されたデータの反復可能ファイルをリストに返すという点で異なります。しかし、Akkaのドキュメントでは、mapと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()

ここAkka先物でのmapとflatMapの違いを誰かが説明できますか?

38
Phil

「通常」Scala(あなたが言うように)では、mapとflatMapはリストとは何の関係もありません(たとえば、Optionをチェックしてください)。

アレクセイはあなたに正しい答えを与えました。ここで、両方が必要な理由を知りたい場合は、先物を作成するときに、Nice 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]]になります。それがあなたがそれを平らにする必要がある理由です。

背後にある概念について学ぶために、これが私が読んだ最高の紹介の1つです。

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

60
paradigmatic

ここAkka先物でのmapとflatMapの違いを誰かが説明できますか?

タイプ、基本的に:

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

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

ここに2つのメソッドの実装を貼り付けています。英語の用語の違いは以下のとおりですそして関数の結果を新しい未来として返します

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

実装との違いは、promiseが完了すると、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

1
Mahesh