The task is to realise recursive method, which 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)
}
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].
As I understand, the problem is that expression inside yield-block must return Seq[Result] for the subsequent wrapping by Monad in Future. But "recursive (result:::res, attempt 1)" return Future. So, instead of the expected Seq[Result] yield contain Future[Seq[Result]].
It there any way to work around this problem?
CodePudding user response:
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:
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
:
for {
res <- retrieve()
out <- if (res.size() result.size() > 20) Future.successful(result:::res)
else recursive (result:::res, attempt 1)
} yield out