We don't have "constraint aliases" in the language today (it's "really not supported" AFAIK) - but I'll let you in on a little secret I discovered. This is really ugly, but believe it or not, it works:
typealias IsFloatColl<T> = T where T: Collection, T.Element: Strideable, T.Element.Stride: BinaryFloatingPoint
extension Collection where IsFloatColl<Element>: Any {
func doSomething() {
// type-checking works.
self.first?.first?.advanced(by: .pi)
}
}
func genericFunc_1D<T>(_ t: T) where IsFloatColl<T>: Any {
t.first?.advanced(by: .pi)
}
func test() {
let flt2D: [[Float]] = []
let dbl2D: [[Double]] = []
let int2D: [[Int]] = []
flt2D.doSomething() // Works.
dbl2D.doSomething() // Works.
genericFunc_1D(flt2D[0]) // Works.
genericFunc_1D(dbl2D[0]) // Works.
// int2D.doSomething()
// Referencing instance method 'doSomething()' on 'Collection' requires that 'Int.Stride' (aka 'Int') conform to 'BinaryFloatingPoint'
// genericFunc_1D(int2D[0])
// Global function 'genericFunc_1D' requires that 'Int.Stride' (aka 'Int') conform to 'BinaryFloatingPoint'
}
It's surprisingly complete - constrained extensions and generics work, and even diagnostics see through the hack and provide good error messages. It can be a big help if you need to repeat long strings of constraints.