Constrained associated type in protocols

can anyone tell me how a constrained associated type is useful in protocols? I feel like an associated type alone is a lot helpful but when combined with constraints does not add much sense. We can substitute the constraining types in place of the associated type and get rid of the associated type.
Thanks in advance

For one, you can have constraints which cannot be existential types themselves because of associatedtype or Self requirements (have you ever seen the error "Protocol 'Equatable' can only be used as a generic constraint because it has Self or associated type requirements"?).

But even beyond that, it allows for more specificity when using types which conform to that protocol. Consider the following example:

protocol Companion {
    var powerLevel: Int { get }

protocol Character {
    associatedtype CompanionType: Companion
    var companion: CompanionType { get }

protocol UnconstrainedCharacter {
    var unconstrainedCompanion: Companion { get }

struct DogCompanion: Companion {
    var powerLevel: Int = 3
    var loyalty: Int = 10

struct Person: Character, UnconstrainedCharacter {
    typealias CompanionType = DogCompanion

    var companion: DogCompanion = DogCompanion()
    var unconstrainedCompanion: Companion {
        return companion


let person = Person()
print(person.companion.loyalty) // 10
print(person.unconstrainedCompanion.loyalty) // Error: Value of type 'Companion' has no member 'loyalty'

Using associatedtype allows the compiler to preserve type information that would otherwise be lost due to the protocol holding a supertype of all Companion-conforming types.


Understood. Thanks a lot.