Scala: for-comprehension with recursive 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)
}

由于这一部分("else recursive (result:::res, attempt + 1)")代码错误,因为它期望Future[Seq[Result]],但实际上返回Future[Object]。

据我所知,问题在于yield块内的表达式必须返回Seq[Result],以便将来由Monad进行后续包装。但是"recursive (result:::res, attempt + 1)"返回的未来。因此,代替预期的Seq[Result] yield包含Future[Seq[Result]]。

有办法解决这个问题吗?

技巧是将您在结束情况下返回的值包装成一个future,以便两种情况下的类型匹配。

你在这里真的不需要for- understanding,在我看来没有它会读得更好:

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- understanding,您仍然可以使用它,只需将yield子句的大部分移动到for中:

for {
res <- retrieve()
out <- if (res.size() + result.size() > 20) Future.successful(result:::res) 
else recursive (result:::res, attempt + 1) 
} yield out


最新更新