2011-07-14 10 views
37

の通常のScalaマップとflatMapの違いは、flatMapはデータの繰り返し可能性をリストにフラットアウトすることです。 しかし、Akkaのドキュメントでは、mapとflatMapは何か違うことをしていますか?Scala 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() 

は、誰かがマップとflatMapとの差が、ここではアッカ先物であるかを説明していただけますか?

+0

私はこれをよりよく理解するのに役立ちます - なぜflatMapを使用するのかhttp://raichoo.blogspot.com/2011/07/from-functions-to-monads-in-scala.html – Phil

答えて

59

は(例えばオプションを確認してください)リストとは何の関係もありません。

アレクシーが正しい答えをくれました。今、なぜ両方が必要なのかを知りたい場合は、先物を作成するときに便利な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]]でてきたwhould:

は今だけのマップを使用した、コンパイラのようなものを行っている可能性があるとします。だからあなたはそれを平らにする必要があります。

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

+7

私はフラット化が種類を平ら可能性が実現しなかった、私の考えでは、それが1つのリストにオブジェクトのリストを平坦化ということでした。だから私の "古い"思考から、私はそれがリストを歩いてそれを平らにしたと思った。実際、Flattenは、あなたがFuture [Future [A]]がList [List [A]]に類似していると言って、型を平坦化することができます。一度このステップを実行すると、私はそれをよりよく理解することができます。 – Phil

+0

ありがとう!特にポストのために!その "セミコロン"が私の心を爆破した! – noru

34

Akka先物のマップとフラットマップの違いは何ですか?

タイプは、基本的には "通常" のScala(あなたが言うように)、マップやflatMapで

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

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

正確には、これは関連性があります未来[A]を返す方法があるとき、未来[A]を得るよりむしろ、未来[A]が必要です。 – Mahesh

+0

あなたがモナドの抽象化に根ざしている、map'と '' flatMap'周りの設計原理の詳細をお知りになりたい場合、私はスカラ座の作成者が、この講義を示唆して、マーティン・オーダーズキーhttps://www.coursera.org/学ぶ/ progfun2 /講義/ 98tNE /講義-1-4-モナド –

1

私はここに二つの方法の実装を貼り付けています:

が背景にある概念について学ぶために、ここで私が読んだ1つの最高のご紹介です。 英語用語の違いが を下回っているとの違いは、約束が完了したときにflatMapが実際の結果との関数を呼び出すことで実装から新しい未来

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

として関数の結果を返します。素晴らしい記事については

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

は読みます:http // danielwestheide.com /ブログ/ 2013/01/16/- 初心者ガイド・ツー・スカーラ - パート9 - 約束 - と - 先物・イン練習。html

関連する問題