What is a primary associated type? Give an example.

1.3.6 · L3 · Interview

Predict first

Does this compile?

let xs: any Collection<Int> = [1, 2, 3]
print(xs.count)
  • Yes
  • No

Mental model. It is a named blank in the contract, so you can write “a Collection of String” instead of “a Collection of something, trust me”.

A primary associated type is declared in angle brackets after the protocol name:

protocol Collection<Element>: Sequence

That lets you constrain the existential or opaque type directly: any Collection<String>, some Sequence<Int>. It does not remove the associated type or make the protocol non-generic — it just gives the compiler (and the reader) a place to pin it.

Collection declares Element as its primary associated type, so you can constrain it in angle brackets with any or some.

Common traps

  • “Primary associated types make PATs into normal protocols.” No — they only let you spell a constraint. A protocol can declare several primary associated types (Dictionary<Key, Value>), but they must be listed in the protocol declaration.
  • Using any Collection without a type argument. Still legal, still fully erased, still limited.

They might follow up with

  • Which stdlib protocols have them? Collection, Sequence, AsyncSequence, Identifiable, and others.
  • Does it help performance? Not directly — it is a spelling improvement. Dispatch is still dynamic through the witness table.

Related questions

  • 1.3.5 What is an associated type? Why can’t you write let x: MyPAT easily?
  • 1.3.7 What is a type eraser (AnyHashable, AnyView, AnyCancellable)? When do you write one?

← What is an associated type? Why can’t you write let x: MyPAT easily?   What is a type eraser (AnyHashable, AnyView, AnyCancellable)? When do… →