Is there any way to implement an extension to a protocol with an associated type requirement which adds conformance to another protocol?

So let's say I have a protocol:

protocol Foo {
    func bar()
}

And I have for instance a generic function which does something with Foo:

func myGeneric<T:Foo>(foo: T) {
    foo.bar()
}

Now let's say I want all sequences of types conforming to Foo also conform to Foo. We have extensions which are conditional on associated type constraints, so I can implement the method just fine:

extension Sequence where Element: Foo  {
    func bar() {
        for foo in self {
            foo.bar()
        }
    }
}

But when I add a where clause to the extension, it no longer appears to be possible to add a protocol conformance. Is there any way to do this?

Hello,

No, you can't extend a protocol in order to have its conforming types automatically conform to another protocol. The language won't let you do that.

However, you can extend any concrete type, and have it conditionally conform to a protocol.

In your case, you could thus have Array, Set, etc. conform to Foo:

protocol Foo {
    func bar()
}
func myGeneric<T:Foo>(foo: T) {
    foo.bar()
}

// Have Array & Set adopt Foo
extension Array: Foo where Element: Foo { }
extension Set: Foo where Element: Foo { }

// Default implementation for all Foo sequences of Foo
extension Sequence where Self: Foo, Element: Foo {
    func bar() {
        for foo in self {
            foo.bar()
        }
    }
}

// Usage
struct MyFoo: Foo {
    func bar() {
        print("bar")
    }
}

// prints "bar" twice
myGeneric(foo: [MyFoo(), MyFoo()])

Ok good to know, thanks for clarifying!

Terms of Service

Privacy Policy

Cookie Policy