Swift: Protocols should be able to be defined with proper type parameters

Originator:vic.gbsmith
Number:rdar://18907606 Date Originated:07-Nov-2014 01:45 PM
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode 6.1 (6A1052d)
Classification:Enhancement Reproducible:Always
 
Summary:
There is currently no way to define a protocol that is properly polymorphic over a generic type. Instead, a fixed type must be selected with a type alias. This makes certain beneficial classes of types inexpressible, for example the class of functors (data structures that can be mapped over, such as arrays and the default map function). If this were allowed, it could be expressed thus:

protocol Functor<T> {
    class func map<A,B>(A -> B), Self<A>) -> Self<B>
}

It is not possible to achieve the same results using the type alias, because Self would no longer be expressing a partial type. We aren’t trying to talk directly about the type T here, but a function that relates classes with different generic types.

In general this would work best if (and possibly require that) type parameters could be partial, that is we could talk about functions like:

func f<M : SomePartialType, A, B>(M<A>) -> M<B>

Steps to Reproduce:
Try and use a generic type over a protocol.

Expected Results:
For this to compile and be usable. I could write code that needs to know nothing about the data structure it is dealing with other than that it supports map.

Actual Results:
This does not compile.

Notes:
The usefulness of this higher level approach to programming is very evident in how common functors and monads and other similar structures are used in functional programming. Optional chaining, list comprehensions, parsers, all can be expressed as monads. If the above changes were implemented in Swift, monads could be expressed this way:

protocol Monad<T> {
    class func return<A>(A) -> Self<A>
    class func >>= <A,B>(Self<A>, A -> Self<B>) -> Self<B>
}

We could, for example, then write mapM, which maps over any array in a monad

func mapM<M: Monad, A, B>(A -> M<B>, [A]) -> M<[B]>

Note the use of M as a partial type.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!