Last active
August 18, 2017 03:21
-
-
Save prachigauriar/ebc27db5c7ca21a89eeb25efc21c3b80 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 | |
public enum Result<Value> { | |
case success(Value) | |
case failure(Error) | |
} | |
// Parent Protocol | |
public protocol Handler { | |
associatedtype Input | |
associatedtype Output | |
func handle(_ result: Result<Input>, completion: @escaping (Result<Output>) -> Void) | |
} | |
// Child Protocol | |
// The goal here is that many types can implement this much simpler method and get Handler | |
// conformance for free. | |
public protocol Transformer : Handler { | |
func transform(_ input: Input) throws -> Output | |
} | |
public extension Transformer { | |
public func handle(_ result: Result<Input>, completion: @escaping (Result<Output>) -> Void) { | |
switch result { | |
case let .success(input): | |
do { | |
completion(.success(try transform(input))) | |
} catch { | |
completion(.failure(error)) | |
} | |
case let .failure(error): | |
completion(.failure(error)) | |
} | |
} | |
} | |
// Conforming struct. I get many errors with most conforming types unless I explicitly create typealiases for | |
// Input and Output. | |
// Errors: | |
// error: ChildProtocolsWithAssociatedTypes.playground:39:15: error: type 'TransformerBlock<BlockInput, BlockOutput>' does not conform to protocol 'Transformer' | |
// public struct TransformerBlock<BlockInput, BlockOutput> : Transformer { | |
// ^ | |
// | |
// ChildProtocolsWithAssociatedTypes.playground:48:17: note: candidate has non-matching type '<BlockInput, BlockOutput> (BlockInput) throws -> BlockOutput' | |
// public func transform(_ input: BlockInput) throws -> BlockOutput { | |
// ^ | |
// | |
// error: ChildProtocolsWithAssociatedTypes.playground:39:15: error: type 'TransformerBlock<BlockInput, BlockOutput>' does not conform to protocol 'Handler' | |
// public struct TransformerBlock<BlockInput, BlockOutput> : Transformer { | |
// ^ | |
// | |
// ChildProtocolsWithAssociatedTypes.playground:18:10: note: protocol requires function 'transform' with type '(<<error type>>) throws -> <<error type>>'; do you want to add a stub? | |
// func transform(_ input: Input) throws -> Output | |
// ^ | |
// | |
// ChildProtocolsWithAssociatedTypes.playground:7:20: note: protocol requires nested type 'Input'; do you want to add it? | |
// associatedtype Input | |
// ^ | |
// | |
// ChildProtocolsWithAssociatedTypes.playground:8:20: note: protocol requires nested type 'Output'; do you want to add it? | |
// associatedtype Output | |
// ^ | |
public struct TransformerBlock<BlockInput, BlockOutput> : Transformer { | |
// public typealias Input = BlockInput | |
// public typealias Output = BlockOutput | |
public let block: (BlockInput) throws -> BlockOutput | |
public init(block: @escaping (BlockInput) throws -> BlockOutput) { | |
self.block = block | |
} | |
public func transform(_ input: BlockInput) throws -> BlockOutput { | |
return try block(input) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment