2016-08-06 63 views
0

私のfor式にif文がないように、私のコードをリファクタリングする方法はありますか?ifフィルタを使用した式でエラーが発生する

私は実行例外を取得しています:

val maybeUserFut: Future[Option[User]] = 
    for { 
      usernameOpt <- lookupUsername("...") 
      if usernameOpt.isDefined 
      userOpt <- getUser(usernameOpt.get) 
     } userOpt 

何パターン私は避けるために使用を開始する必要があります。オプションは以下のように定義されており、それが問題を引き起こしている場合、私はやっている

[NoSuchElementException: Future.filter predicate is not satisfied] 

このエラー?

+2

http://stackoverflow.com/questions/17869624/scala-future-with-filter-in-for-comprehension –

答えて

0
for { 
    usernameOpt <- lookupUsername("...") 
    if usernameOpt.isDefined 
    userOpt <- getUser(usernameOpt.get) 
} yield userOpt 

lookupUsername("...") 
    .withFilter({ usernameOpt => usernameOpt.isDefined }) 
    .flatMap({ usernameOpt => 
    getUser(usernameOpt.get).map({ userOpt => 
     userOpt 
    }) 
}) 

Future.withFilterに変換される(source)のように定義される:

def filter(p: T => Boolean)(implicit executor: ExecutionContext): Future[T] = 
    map { 
    r => if (p(r)) r else throw new NoSuchElementException("Future.filter predicate is not satisfied") 
    } 

ので仕事に行くされている単純な変換が存在しません。

私はおそらくのようなもの書くでしょう:あなたはfor理解の構文を使用する場合は、Futureに明示的なリフトを抽象化しScalaz OptionTのようなモナド変換(例えばcase None => Future.successful(None))が必要になります

lookupUsername("...").flatMap({ usernameOpt => 
    usernameOpt match { 
    case None   => Future.successful(None) 
    case Some(username) => getUser(username) 
    } 
}) 

を:

import scalaz._ 
import Scalaz._ 
import scalaz.OptionT._ 

val maybeUserFut: Future[Option[User]] = 
    (for { 
    username <- optionT(lookupUsername("...")) 
    user <- optionT(getUser(username)) 
    } yield user).run 
関連する問題