2017-01-17 5 views
0

このクエリを正しく取得しようとしていますが、エラーが発生しています。まず、searchUserは、userの一意のIDを含む一致するUserEntriesのシーケンスを返します。また、userIdのそれぞれに対して、別のテーブルから他のユーザー情報+アドレスを取得します。Scala:エラーを含む理解のために内部でクエリを構成する

コード:使用するAPIについて

def searchUsers(pattern: String) = auth.SecuredAction.async { 
    implicit request => 
    usersService.searchUser(pattern) flatMap { usrList => 
     for { 
     u <- usrList 
     ui <- usersService.getUsersWithAddress(u.id) 
     } yield { 
     Ok(views.html.UserList(ui)) 
     } 
    } 
} 

署名:

def searchUser(pattern: String): Future[Seq[UserEntry]] = ...  
def getUsersWithAddress(userId: Long): Future[Seq[(UserProfile, Seq[String])]] = ... 

がエラー:

[error] modules/www/app/controllers/Dashboard.scala:68: type mismatch; 
[error] found : scala.concurrent.Future[play.api.mvc.Result] 
[error] required: scala.collection.GenTraversableOnce[?] 
[error]   ui <- usersService.getUsersWithAddress(u.id) 
[error]   ^
[error] one error found 
[error] (www/compile:compileIncremental) Compilation failed 

私はライン "U < - usrList" をコメントアウトした場合やユーザーIDをハードコーディング"ui < - usersService.getUsersWithAddress(1L)"のような次の行では動作します。私の欠点は何ですか?

答えて

1

for comprehensionで複数の発電機を使用する場合、モナドは同じタイプでなければなりません。例えば。あなたはできません:

scala> for{ x <- Some("hi"); y <- List(1,2,3) } yield (x,y) 
<console>:11: error: type mismatch; 
found : List[(String, Int)] 
required: Option[?] 
      for{ x <- Some("hi"); y <- List(1,2,3) } yield (x,y) 
           ^

あなたができることは、お互いを正しいタイプに一致するように変換することです。上記の例では、それは次のようになります。あなたの特定のケースで

scala> for{ x <- Some("hi").toSeq; y <- List(1,2,3) } yield (x,y) 
res2: Seq[(String, Int)] = List((hi,1), (hi,2), (hi,3)) 

、あなたの発電機の一つはGenTraversableOnceであり、他方は未来です。おそらくFuture.successful(theList)を使用して2つの未来を得ることができます。例えば、ここでの回答を参照してください:

Unable to use for comprehension to map over List within Futureブライアンの答えは@に基づいて

+0

にgetUserWithAddressの署名を変更しなければならなかった私は、Uを折り返す場合< - Future.successfulとusrList()私が「で終わる値IDがメンバーではありませんSeq [models.UserEntry]の "私は "u"がシーケンスではなくアイテムになることを望んでいました。 2番目のジェネレータは1つのアイテムへの参照が必要です - どのようにすればいいですか(私は非機能的な言語で伝統的なforループを考えることができますが、ここではありません) – srvy

+0

あなたの答えに基づいてチェーンをたどり、私はコメントに書式設定されたコードを置くことができないので、私はそれを私の答えとして追加します - しかし、あなたにクレジットを与えるためにあなたを受け入れます! – srvy

0

は(コメントとしてコードのフォーマッタブロックに入ることができませんでした - そう答えとして追加)加工した次..ソリューションに到着しました:

usersService.searchUser(pattern) flatMap { usrList => 
    val q = for { 
     u <- usrList 
    } yield (usersService.getUserWithAddress(u.id)) 
    val r = Future.sequence(q) 
    r map { ps => 
     Ok(views.html.UserList(ps)) 
    } 
    } 

理解のために先物が蓄積され、次に配列が平坦化されてマッピングされました。これがどのように行われるのが欲しいです!

注:また、私の代わりに配列のX [X]

関連する問題