[英]Scala: for-comprehension with recursive Future
The task is to realise recursive method, which returns Future任务是实现递归方法,返回Future
def recursive (result:List[Result], attempt: Int):Future[Seq[Result]] = attempt match {
case a if a < 3 => {
for {
res <- retrive()
} yield {
if ((result:::res).size > 20) res
else recursive (result:::res, attempt + 1)
}
}
case => Future(Seq.empty)
}
And due to this part ("else recursive (result:::res, attempt + 1)" ) code failed with error, as it expects Future[Seq[Result]], but in fact return Future[Object].并且由于这部分(“else recursive (result:::res, try + 1)”)代码失败并出现错误,因为它期望 Future[Seq[Result]],但实际上返回 Future[Object]。
As I understand, the problem is that expression inside yield-block must return Seq[Result] for the subsequent wrapping by Monad in Future.据我了解,问题在于 yield-block 中的表达式必须返回 Seq[Result] 以供 Monad 在 Future 中进行后续包装。 But "recursive (result:::res, attempt + 1)" return Future.但是“递归 (result:::res, try + 1)”返回 Future。 So, instead of the expected Seq[Result] yield contain Future[Seq[Result]].因此,代替预期的 Seq[Result] 产量包含 Future[Seq[Result]]。
It there any way to work around this problem?有什么办法可以解决这个问题吗?
The trick is to wrap the value you are returning in the terminal case into a future, so that the types match for both cases.诀窍是将您在终端案例中返回的值包装到未来,以便类型匹配两种情况。
You don't really need a for-comprehension here, it would read a lot better without it IMO:你真的不需要在这里理解,没有它IMO会更好读:
retrieve.flatMap {
case r if r.size + result.size > 20 => Future.successful(result:::r) // you are not prepending result in your snippet, I think, it's a bug ...
case r => recursive (result:::r, attempt + 1)
}
If you are partial to for-comprehension for some reason, you can still use it, just need to move most of the yield
clause inside the for
:如果你出于某种原因偏向于理解,你仍然可以使用它,只需将大部分yield
子句移到for
:
for {
res <- retrieve()
out <- if (res.size() + result.size() > 20) Future.successful(result:::res)
else recursive (result:::res, attempt + 1)
} yield out
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.