2016-07-29 14 views
1

以下のコードは、実際のコードを簡略化したものです。ドメインモデルcase object FutTestcase class FutTestを "継承"しましたが、これは変更できません。実際のドメインモデルはデータベースから提供されるので、私はFuture approachが有効だと信じていますが、それは私が理解していない問題を引き起こします。Scala将来の奇妙なコンパイルエラー

import org.scalatest.FunSpec 
import scala.concurrent.Future 
import scala.concurrent.ExecutionContext.Implicits.global 

case object FutTest { 
    def create(sz: Int) = { FutTest(sz) } 
} 

case class FutTest(size: Int) 

class FutureTest extends FunSpec { 
    def one(v: Int): Future[FutTest] = { 
    Future { FutTest.create(v) } 
    } 
    def two(t: FutTest) = { 
    Future { FutTest.create(t.size) } 
    } 

    def compileError1: Future[FutTest] = { 
    one(10).map(f => two(f)) 
    } 

    def compileError2: Future[FutTest] = { 
    for { o <- one(10) } yield (two(o)) 
    } 
} 

エラーメッセージ:

[INFO] Using incremental compilation 
[INFO] Compiling 7 Scala sources and 5 .. target/test-classes... 
[ERROR] domain.FutureTest.scala:25: type mismatch; 
found : scala.concurrent.Future[domain.FutTest] 
required: domain.FutTest 
[ERROR]  one(10).map(f => two(f)) 
[ERROR]      ^
[ERROR] domain/FutureTest.scala:29: type mismatch; 
found : scala.concurrent.Future[domain.FutTest] 
required: domain.FutTest 
[ERROR]  for { o <- one(10) } yield (two(o)) 

IプレーンInt代わりにFutTestと上記のコードを試み、すべてが大丈夫です。なぜコンパイラが不平を言っているのですか?既存のドメインに触れることなくこれをどうやって解決できるのでしょうか?

+0

私はあなたが 'Int'と' FutTest'を交換する場合、これが動作することを信じていません。 –

答えて

5

あなたが望むのはflatMapです。

one(10).flatMap(f => two(f)) 

または

理解のために使用
one(10).flatMap(two) 

for { o <- one(10); t <- two(o) } yield t 
4

One()Futuretwo()を返すも、あなたがflatMap代わりのmapに必要Futureを返します。 two()にマップすると、結果はFuture[Future[FutTest]]となり、平坦化する必要があります。

one(10).flatMap(f => two(f)) 

を行うことはトリックを行う必要があります。