> final class Something<T> { > > let value: T > > init(initial: T) { > value = initial > } > > } > > extension Something { > > class func zip<A, B>(a: A, _ b: B) -> Something<(A, B)> { > let initial = (a, b) > return Something<(A, B)>(initial: initial) > } > > } > > How come I can’t call zip without explicitly specifying return type? > > // ERROR: Cannot invoke `zip` with an argument list of type `(Int, Int)` > let y = Something.zip(1, 2) > > // OK: Works but it’s unacceptable to require this on caller's side > let x = Something<(Int, Int)>.zip(1, 2)
The reason you're seeing this is that there's nothing in this call: let y = Something.zip(1, 2) That tells Swift what `T` should be. The return type of the `zip` method is not connected to T; you can actually put any random type in the angle brackets after Something: let y = Something<UICollectionViewDelegateFlowLayout>.zip(1, 2) Unfortunately, Swift doesn't currently have the features needed to properly connect `T` to the return type. If the language were more sophisticated, you could say something like this: extension<A, B> Something where T == (A, B) { class func zip(a: A, _ b: B) -> Something { let initial = (a, b) return Something(initial: initial) } } But for now, you'll have to make do with this horrible hack, which works by meaninglessly reusing the T type parameter: extension Something { class func zip<B>(a: T, _ b: B) -> Something<(T, B)> { let initial = (a, b) return Something<(T, B)>(initial: initial) } } Hope this helps, -- Brent Royal-Gordon Architechies _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users