Scala:for-comprehension with recursive Future
Scala: for-comprehension with recursive Future
任务是实现递归方法,即returns 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)
}
并且由于这部分(“else recursive (result:::res, attempt + 1)”)代码因错误而失败,正如它所期望的 Future[Seq[Result]],但实际上 return 未来[对象].
据我了解,问题在于 yield-block 中的表达式必须 return Seq[Result] 才能由 Monad 在 Future 中进行后续包装。但是“递归(结果:::res,尝试+ 1)” return 未来。因此,而不是预期的 Seq[Result] yield 包含 Future[Seq[Result]].
有什么办法可以解决这个问题吗?
诀窍是将您在终端案例中返回的值包装到未来,以便两种情况的类型匹配。
这里你真的不需要 for-comprehension,没有它阅读起来会好很多 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)
}
如果你因为某些原因偏向for-comprehension,你仍然可以使用它,只需要将大部分yield
子句移动到for
:
for {
res <- retrieve()
out <- if (res.size() + result.size() > 20) Future.successful(result:::res)
else recursive (result:::res, attempt + 1)
} yield out
任务是实现递归方法,即returns 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)
}
并且由于这部分(“else recursive (result:::res, attempt + 1)”)代码因错误而失败,正如它所期望的 Future[Seq[Result]],但实际上 return 未来[对象].
据我了解,问题在于 yield-block 中的表达式必须 return Seq[Result] 才能由 Monad 在 Future 中进行后续包装。但是“递归(结果:::res,尝试+ 1)” return 未来。因此,而不是预期的 Seq[Result] yield 包含 Future[Seq[Result]].
有什么办法可以解决这个问题吗?
诀窍是将您在终端案例中返回的值包装到未来,以便两种情况的类型匹配。
这里你真的不需要 for-comprehension,没有它阅读起来会好很多 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)
}
如果你因为某些原因偏向for-comprehension,你仍然可以使用它,只需要将大部分yield
子句移动到for
:
for {
res <- retrieve()
out <- if (res.size() + result.size() > 20) Future.successful(result:::res)
else recursive (result:::res, attempt + 1)
} yield out