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