Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Scala: for-comprehension with recursive Future

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]].

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

It there any way to work around this problem?

>Solution :

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
        
          
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading