为什么for-comp中的for-comp不起作用

Bla*_*man 1 scala playframework

以下工作正常:

def show(id: Int) = myAction asyc {

  for {
    users <- userService.getAll()
    locations <- locationService.getByUsers(users)
  } yield {
    Ok("hi")
  }

}
Run Code Online (Sandbox Code Playgroud)

但如果我这样做:

 for {
    users <- userService.getAll()
    locations <- locationService.getByUsers(users)
  } yield {
    for {
      f1 <- ...
      f2 <- ....
    } yield {
      Ok("hi")
    }
  }
Run Code Online (Sandbox Code Playgroud)

我收到类型不匹配错误:

found   : scala.concurrent.Future[play.api.mvc.Result]
[error]  required: play.api.mvc.Result
[error]           f1 <- ....
Run Code Online (Sandbox Code Playgroud)

希望有人能为我解释一下.

dan*_*xon 6

添加类型注释可能有助于更清楚地了解正在发生的事情:

val result: Future[Future[Result]] = for {
  users <- userService.getAll()
  locations <- locationService.getByUsers(users)
} yield {
  val innerResult: Future[Result] = for {
    f1 <- ...
    f2 <- ....
  } yield {
    Ok("hi")
  }
  innerResult
}
Run Code Online (Sandbox Code Playgroud)

通过产生一个Future[Result](innerResult),你可以使最外层for成为类型Future[Future[Result]].

我们知道它result必须是Future [???]类型(由第一个生成器的类型决定userService.getAll()).它结束了Future[Future[Result]]因为你产生了一个Future[Result].

解决方案是产生一个Resultintead:

def foo(users: Seq[User], locations: Seq[Location]): Future[Result] = {
  for {
    f1 <- ...
    f2 <- ....
  } yield {
    Ok("hi")
  }
}

for {
  users <- userService.getAll()
  locations <- locationService.getByUsers(users)
  result <- foo(users, locations)
} yield result
Run Code Online (Sandbox Code Playgroud)