Last active
April 21, 2016 20:24
-
-
Save elm4ward/9cfbdea339992051f51870265052f7ec 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
// ---------------------------------------------------------------------------------------------------- | |
// Protocol Flow in Swift | |
// | |
// http://elm4ward.github.io/swift/protocols/2016/04/02/protocollisions.html | |
// | |
// 1. The Protocols | |
// 2. The Flow | |
// 3. String Example | |
// 4. Custom Example | |
// ---------------------------------------------------------------------------------------------------- | |
// ---------------------------------------------------------------------------------------------------- | |
// MARK: - 1. The Protocols | |
// | |
// Three of a kind | |
// ---------------------------------------------------------------------------------------------------- | |
protocol Fetchable { | |
associatedtype FetchedType | |
static var all: [FetchedType] { get } | |
} | |
protocol Changeable { | |
associatedtype ChangeResultType | |
static var changeTo: Self -> ChangeResultType { get } | |
} | |
protocol Mergeable { | |
associatedtype MergeResultType | |
static var merge: (MergeResultType, Self) -> MergeResultType { get } | |
static var identity: MergeResultType { get } | |
} | |
// ---------------------------------------------------------------------------------------------------- | |
// MARK: - 2. The One and only flow implementation | |
// | |
// Taking care of all 3 protocols | |
// ---------------------------------------------------------------------------------------------------- | |
extension Fetchable where Self.FetchedType: Changeable, Self.FetchedType.ChangeResultType: Mergeable { | |
typealias MergeableType = Self.FetchedType.ChangeResultType | |
typealias ChangeableType = Self.FetchedType | |
static func fetchItChangeItMergeIt() -> MergeableType.MergeResultType { | |
return all | |
.map(ChangeableType.changeTo) | |
.reduce(MergeableType.identity, combine: MergeableType.merge) | |
} | |
} | |
// ---------------------------------------------------------------------------------------------------- | |
// MARK: - 3. Example - String | |
// ---------------------------------------------------------------------------------------------------- | |
extension String: Fetchable { | |
static let all = ["a", "b", "c"] | |
} | |
extension String: Changeable { | |
static let changeTo: String -> Int = { $0.characters.count } | |
} | |
extension Int: Mergeable { | |
static let identity = 0 | |
static let merge: (Int, Int) -> Int = (+) | |
} | |
String.fetchItChangeItMergeIt() | |
// -> 3 | |
// ---------------------------------------------------------------------------------------------------- | |
// MARK: - 4. Example - Cusotm | |
// | |
// we can even combine the Protocols | |
// ---------------------------------------------------------------------------------------------------- | |
protocol TheWholeEnchilada: Fetchable, Changeable {} | |
struct Data { | |
let name: String | |
} | |
extension Data: TheWholeEnchilada { | |
static let all = [Data(name: "a"), Data(name: "bb"), Data(name: "ccc")] | |
static let changeTo: Data -> String = { $0.name } | |
} | |
extension String: Mergeable { | |
static let identity = "" | |
static let merge: (String, String) -> String = { $0.isEmpty ? $1 : $0 + ", " + $1 } | |
} | |
Data.fetchItChangeItMergeIt() | |
// -> "a, bb, ccc" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment