2013-11-20 4 views
6

forを使ってリストを反復し、Futureを返すユーティリティを使用して各要素を変換しようとしています。短いストーリー、それはコンパイルされません、なぜ私は理解したいと思います。私はthis questionと似ていますが、大きな助けとなりましたが、私がやろうとしていることはさらに簡単になりました。私のような何かやろうとしている:スカラ先物とコレクションを補完のために組み合わせる

import scala.concurrent.Future 
import scala.concurrent.ExecutionContext.Implicits.global 

val numberList = List(1, 2, 3) 
def squareInTheFuture(number: Int): Future[Int] = Future { number * number} 
val allTheSquares = for { 
          number <- numberList 
          square <- squareInTheFuture(number) 
         } yield { square } 

をそして私が取得することである:

error: type mismatch; found : scala.concurrent.Future[Int] required: scala.collection.GenTraversableOnce[?] square <- squareInTheFuture(number) ^

誰かが、これは動作しませんし、最善の選択肢は何か、なぜ私が理解するのに役立つことはできますか?

答えて

7

flatMapは、numberListsquareInTheFuture(number)の型コンストラクタが同じであること(コレクションライブラリが暗黙的に行っている変換をすべてモジュールとする)が必要であることを示します。それはここでは当てはまりません。

val allTheSquares: Future[List[Int]] = 
    Future.traverse(numberList)(squareInTheFuture) 

これは、非同期ですべての計算を開始し、一度完成され、将来を返します。

val allSquaresInTheFuture: Future[List[Int]] = 
    Future.traverse(numberList)(squareInTheFuture) 
2

あなたの理解のためには、

val allTheSquares = numberList.flatMap(number => squareInTheFuture(number)) 

flatMapと同じであることは、それは引数の関数がGenTraversableOnce[Int]を返します、しかし、あなたが不一致したがって、Future[Int]を返すことが必要です。

9

Future companion objectはあなたが望むものを正確に行いtraverse方法があります。その代わり、これはトラバーサルですこれらすべての先物が完成します。

2

@Leeが正しいです。さらにとして、あなたは、並列計算をやろうとしている場合:

val allTheSquares: Future[List[Int]] = Future.traverse(numberList)(squareInTheFuture) 

val numberList = List(1, 2, 3) 
    val allTheSquares = numberList.par.map(x => x * x)(breakOut) 

あなたは本当にFutureをしたい場合

関連する問題