From https://figure.ink/blog/2021/6/13/cleaning-up-async-without-swift-55
source link: https://gist.github.com/jemmons/71104d11e8598220cab48c651c8dbf4f
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Instantly share code, notes, and snippets.
import Foundation typealias Continuation<Ret> = (Ret) -> Void typealias ContinuationMonad<Value> = (@escaping Continuation<Value>) -> Void typealias Transform<T,U> = (T) -> ContinuationMonad<U>
func async<Value>(_ wrappedValue: Value) -> ContinuationMonad<Value> { { $0(wrappedValue) } }
func flatMap<T,U>(_ monad: @escaping ContinuationMonad<T>, _ transform: @escaping Transform<T,U>) -> ContinuationMonad<U> { { continuation in monad { wrappedValue in transform(wrappedValue)(continuation) } } }
public func curry<T, U, Z>(_ ƒ: @escaping (T, U)->Z) -> (T) -> (U) -> Z { { t in { u in ƒ(t, u) } } }
precedencegroup BackApplication { associativity: left } infix operator <|: BackApplication
public func <| <T, U>(ƒ: (T)->U, t: T) -> U { ƒ(t) }
precedencegroup FlatMapOperator { higherThan: BackApplication associativity: left } infix operator >>=: FlatMapOperator
func >>=<T,U> (lhs: @escaping ContinuationMonad<T>, rhs: @escaping Transform<T,U>) -> ContinuationMonad<U> { flatMap(lhs, rhs) }
func fetchAvatar(user: UUID, completion: @escaping Continuation<URL>) { // Delay added to simulate an actual async task. DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) { completion(URL(string: "/\(user.uuidString)")!) } }
// For the sake of demonstration, we’re pulling a // string out of the url rather than fetching an // image actual image. func fetchImage(url: URL, completion: @escaping Continuation<String>) { DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) { completion(url.path) } }
func fetchPortrait(user: UUID, completion: @escaping Continuation<String>) { async(user) >>= curry(fetchAvatar) >>= curry(fetchImage) <| completion }
fetchPortrait(user: UUID()) { print($0) } //> After two seconds, prints a UUID.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK