Retry on failure: a simple higher-order function in Scala
Scala can be so beautiful in its simplicity <3
Here’s a HOF retry
that runs a function that can fail N times before giving up:
def retry[R](retries: Int)(fn: => Option[R]): Option[R] = { if (retries > 0) fn orElse retry(retries - 1)(fn) else None }
We can obviously made it a lot more confusing using fold
:
def retry[R](retries: Int)(fn: => Option[R]): Option[R] = { if (retries > 0) fn.fold(retry(retries - 1)(fn))(_ => fn) else None }
Or we can strip away all its elegance and resort to pattern matching (eww)
def retry[R](retries: Int)(fn: => Option[R]): Option[R] = { if (retries > 0) { fn match { case None => retry(retries - 1)(fn) case Some(result) => Some(result) } } else None }
A way to use this is to put the retry
method in its own trait
and use it as follows:
object Test extends Retry { } // will fail twice before succeeding var failedCount = 0 Test.retry(3) { if (failedCount < 2) { failedCount += 1 println("fail") None } else Some("yay!") }