Last active
June 26, 2021 21:02
-
-
Save pgherveou/617e6d4a523b5e1c44d4774984ed83e0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import PlaygroundSupport | |
PlaygroundPage.current.needsIndefiniteExecution = true | |
/// define an operation success or error result | |
enum Result<T> { | |
case error(Error) | |
case success(T) | |
} | |
/// define a generator function result. | |
/// a generator can yield multiple values before returning | |
enum IteratorResult<Yield, Return> { | |
case yield(Yield) | |
case done(Return) | |
} | |
/// a generator is a function that return an IteratorResult every time its called | |
typealias Generator<Yield, Return, Next> = (Next?) -> IteratorResult<Yield, Return> | |
typealias Thunk<T> = (@escaping (Result<T>) -> Void) -> Void | |
/// run a generator step bt step until its done | |
func runner<T, V>(_ generator: Generator<Thunk<T>, Thunk<V>, T>) -> Void { | |
func run(value: T?, callback: @escaping (Result<V>) -> Void) { | |
let it = generator(value) | |
switch it { | |
case .yield(let thunk): | |
thunk() { (result: Result<T>) -> Void in | |
switch result { | |
case .error(let err): | |
callback(.error(err)) | |
case .success(let value): | |
print("yield", value) | |
return run(value: value, callback: callback) | |
} | |
} | |
case .done(let thunk): | |
thunk(callback) | |
} | |
} | |
run(value: nil) { print($0) } | |
} | |
/// example of generator that yield incremented number and returns 10 | |
func incGenerator() -> Generator<Thunk<Int>, Thunk<Int>, Int> { | |
return { (prev: Int?) in | |
let next = (prev ?? 0) + 1 | |
let thunk: Thunk<Int> = { callback in | |
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { | |
callback(Result.success(next)) | |
} | |
} | |
return next < 10 | |
? .yield(thunk) | |
: .done(thunk) | |
} | |
} | |
runner(incGenerator()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You're missing an @escaping decorator on line 23