There is no support in the standard library, and probably will not for some time. There are great third-party libraries, but if you don't want them, you can define the minimum yourself (I use Swift 3 here):
enum Result<R> { case Success(R) case Failure(ErrorProtocol) } typealias Async<A, B> = (a: A, handler: (Result<B>) -> Void) -> Void infix operator • { associativity right precedence 190 } func •<A, B, C>(f: Async<A, B>, g: Async<B, C>) -> Async<A, C> { return { a, handler in f(a: a, handler: { result in switch result { case .Success(let b): g(a: b, handler: handler) case .Failure(let e): handler(.Failure(e)) } }) } }
Usage example:
func f(n: Int, h: (Result<String>) -> ()) { h(.Success(n.description)) } func g(s: String, h: (Result<Int>) -> ()) { h(.Success(s.characters.count)) } let chained = f • g chained(a: 10) { result in switch result { case .Success(let r): print("Success: \(r)") case .Failure(let e): print("Error: \(e)") } }
Extended usage example:
enum Error : ErrorProtocol { case NoResult case StringDecoding } extension URLSession { func getData(with url: URL, completionHandler: (Result<(Data, URLResponse)>) -> Void) { let task = dataTask(with: url) { (data, response, error) in if let error = error { completionHandler(.Failure(error)) } else if let data = data, response = response { completionHandler(.Success((data, response))) } else { completionHandler(.Failure(Error.NoResult)) } } task.resume() } } func decode(d: (Data, URLResponse), handler: (Result<String>) -> Void) { DispatchQueue(label: "async").async{ if let string = String(data: d.0, encoding: .utf8) { handler(.Success(string)) } else { handler(.Failure(Error.StringDecoding)) } } } let getString = URLSession.shared().getData • decode getString(a: URL(string: "https://www.reddit.com")!) { result in switch result { case .Success(let string): print(string) case .Failure(let e): print(e) } }
source share