Repeating function call until we'll get non-empty Option result in Scala

loops, scala

Solution

You can use `Stream`'s `continually` method to do precisely this:

val res = Stream.continually(tryToGetResult).flatMap(_.toStream).head

Or (possibly more clearly):

val res = Stream.continually(tryToGetResult).dropWhile(!_.isDefined).head

One advantage of this approach over explicit recursion (besides the concision) is that it's much easier to tinker with. Say for example that we decided that we only wanted to try to get the result a thousand times. If a value turns up before then, we want it wrapped in a `Some`, and if not we want a `None`. We just add a few characters to our code above:

Stream.continually(tryToGetResult).take(1000).flatMap(_.toStream).headOption

And we have what we want. (Note that the `Stream` is lazy, so even though the `take(1000)` is there, if a value turns up after three calls to `tryToGetResult`, it will only be called three times.)

Problem

A very newbie question in Scala - how do I do "repeat function until something is returned meets my criteria" in Scala? Given that I have a function that I'd like to call until it returns the result, for example, defined like that: ``` def tryToGetResult: Option[MysteriousResult] ``` I've come up with this solution, but I really feel that it is ugly: ``` var res: Option[MysteriousResult] = None do { res = tryToGetResult } while (res.isEmpty) doSomethingWith(res.get) ``` or, equivalently ugly: ``` var res: Option[MysteriousResult] = None while (res.isEmpty) { res = tryToGetResult } doSomethingWith(res.get) ``` I really feel like there is a solution without `var` and without so much hassle around manual checking whether `Option` is empty or not. For comparison, Java alternative that I see seems to be much cleaner here: ``` MysteriousResult tryToGetResult(); // returns null if no result yet MysteriousResult res; while ((res = tryToGetResult()) == null); doSomethingWith(res); ``` To add insult to injury, if we don't need to `doSomethingWith(res)` and we just need to return it from this function, Scala vs Java looks like that: Scala ``` def getResult: MysteriousResult = { var res: Option[MysteriousResult] = None do { res = tryToGetResult } while (res.isEmpty) res.get } ``` Java ``` MysteriousResult getResult() { while (true) { MysteriousResult res = tryToGetResult(); if (res != null) return res; } } ```

Original source