Hello, I'm struggling with Swift generics. It seems like I'm missing something. Here is an example of what I want to create:
struct TestCollections<Collection1: MyCollection<Int>, Collection2: MyCollection<String>> {
let colletion1: Collection1
let collection2: Collection2
func test() -> Collection2 {
colletion1.specificFlatMap { _ in return collection2 }
}
}
// Should work correctly because Array == Array
let collection1 = TestCollections(colletion1: [1, 2, 3], collection2: ["1", "2", "3"])
let result1: [String] = collection1.test()
// Should work correctly because Result == Result
let collection2 = TestCollections(colletion1: Result<Int, Error>.success(1), collection2: Result<String, Error>.success("2"))
let result2: Result<String, Error> = collection2.test()
// Should show Error because Result != Array
TestCollections(colletion1: Result<Int, Error>.success(1), collection2: ["1", "2", "3"])
// Should show Error because Array != Result
TestCollections(colletion1: [1, 2, 3], collection2: Result<String, Error>.success("2"))
But I can't find the way to create correct protocol:
protocol MyCollection<Element> {
associatedtype Element
// Just example
func specificFlatMap<T: MyCollection>(_ body: (Element) -> T) -> T
}
Is it possible to do it and iherit in these ways?
extension Result: MyCollection where Failure == Error {
typealias Element = Success
func specificFlatMap(_ body: (Element) -> Result<Element, Error>) -> Result<Element, Error> {
switch self {
case .success(let value):
return body(value)
case .failure(let err):
return .failure(err)
}
}
}
extension Array: MyCollection {
func specificFlatMap(_ body: (Element) -> Array<Element>) -> Array<Element> {
flatMap { element in
return body(element)
}
}
}