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:
1 2 3 | 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
:
1 2 3 4 5 | 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)
1 2 3 4 5 6 7 8 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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!" ) } |