Zaphod
Zaphod

Reputation: 7290

Generics of generics in Swift 3

I'm facing a strange problem, here it is: I wish to constraint one generic type with another generic type.

Let me explain, I have a simple generic type:

class Simple<T : Equatable> { ... }

And I wish to have another generic type constraint with this simple (generic) type:

class Complex<U : Simple> { ... } // WRONG!

Of course that does not compile nor this:

class Complex<U : Simple<T : Equatable>> { ... } // WRONG!

nor:

class Complex<U : Simple<T>> where T : Equatable { ... } // WRONG!

The only way I found is:

class Complex<T : Equatable, U : Simple<T>> { ... } 

So I need to repeat T on each instanciation:

let x = Complex<Date, Simple<Date>>()

Worst, imagine if I have something like that:

class SimpleThing : Simple<Thing> { ... }
let y = Complex<Thing, SimpleThing>()

How can I declare Complex for using it this way?:

let x = Complex<Simple<Date>>()
let y = Complex<SimpleThing>()

Is it only possible in Swift 3?

Thanks in advance.

Upvotes: 4

Views: 2031

Answers (1)

Mick MacCallum
Mick MacCallum

Reputation: 130222

If I'm understanding what you want to do correctly, this can be achieved with a protocol with an associated type. You can make your Simple class conform to it, and then constrain the type parameter on Complex to be its conforming types, and finally, place qualifications on the associated type. Should be something like this:

protocol SimpleType {
    associatedtype Assoc
}

class Simple<T: Equatable>: SimpleType {
    typealias Assoc = T
}

class Complex<U: SimpleType> where U.Assoc: Equatable {
    init() {

    }
}

let c = Complex<Simple<Date>>()

Upvotes: 5

Related Questions