Search code examples
swiftgenericsswift-protocolsassociated-types

Swift subprotocol with associated type


I'd like to know how this type of relation (example in kotlin) would be expressed in Swift

interface Index<K, V> {
  fun getAll(key: K): Sequence<V>
}

I tried to use protocols with associated types, like this:

protocol Index {
    associatedtype Key
    associatedtype Value
    associatedtype Result: Sequence where Sequence.Element == Value

    func getAll(key: Key) -> Result
}

but this didn't work (Associated type 'Element' can only be used with a concrete type or generic parameter base)

Then, as a workaround, i tried this:

protocol Index {
    associatedtype Key
    associatedtype Value

    func get<T: Sequence>(key: Key) -> T where T.Element == Value
}

But this doesn't really seem like the right / idiomatic way to do it.

There are only two constraints:

  1. Sequence can't be a concrete type
  2. None of the methods on Index have a meaningful implementation

Notes:

  • There will be a class / type that implements Sequence that is specific to each implementation of Index

I'm open to any other structural change! Thanks in advance.


Solution

  • You need to use the associated type's name, not the inherited protocol's name:

    associatedtype Result: Sequence where Result.Element == Value
    //                                    ^^^^^^
    

    Note that Swift's standard library now includes a type named Result, so you might want to use a different name for your associatedtype. I use Answer in my own code:

    associatedtype Answer: Sequence where Answer.Element == Value
    

    (In Smalltalk, return values are called “answers”.)