Skip to content

Instantly share code, notes, and snippets.

@Rheeseyb
Created October 2, 2016 10:38
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Rheeseyb/b85634692cb89a6861f54d96e181f0dc to your computer and use it in GitHub Desktop.
In Swift, repeatedly attempt a series of failable functions, failing if any of them fail
import Cocoa
enum Failable<T> {
case fail
case success(T)
func map<U>(fn: (T) -> U) -> Failable<U> {
switch self {
case .fail: return .fail
case let .success(t): return .success(fn(t))
}
}
func flatMap<U>(fn: (T) -> Failable<U>) -> Failable<U> {
switch self {
case .fail: return .fail
case let .success(t): return fn(t)
}
}
}
func repeatedlyAttempt<T>(attempts: Int, fn: () -> Failable<T>) -> Failable<T> {
guard attempts > 0 else { return .fail }
let attempted = fn()
switch attempted {
case .success(_): return attempted
case .fail: return repeatedlyAttempt(attempts: attempts - 1, fn: fn)
}
}
func randomlyFail<T>(fn: () -> T) -> Failable<T> {
return (arc4random_uniform(2) == 1) ? .success(fn()) : .fail
}
func doThing(i: Int) -> String {
return "\(i)"
}
func reverseDoThing(s: String) -> Int {
return Int(s)!
}
let failableDoThing = { i in randomlyFail(fn: { doThing(i: i) }) }
let failableReverseDoThing = { s in randomlyFail(fn: { reverseDoThing(s: s) }) }
repeatedlyAttempt(attempts: 5){ failableDoThing(10) }
.flatMap{s in repeatedlyAttempt(attempts: 5){ failableReverseDoThing(s) } }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment