Protocol doesn't conform to itself: Any workaround?


(Charles Srstka) #1

So, the pitfall below seems to be fairly well-known, as I was able to find previous references to it on the list:

···

--

protocol P { func foo() }
struct S: P { func foo() { print("foo") } }

func doSomething<C: CollectionType where C.Generator.Element: P>(c: C) {
  for each in c {
    each.foo()
  }
}

let arr: [P] = [S()]

doSomething(arr) // error: cannot invoke 'doSomething' with an argument list of type '([P])’

--

And, of course, if we go the opposite way:

--

protocol P { func foo() }
struct S: P { func foo() { print("foo") } }

func doSomething<C: CollectionType where C.Generator.Element == P>(c: C) {
  for each in c {
    each.foo()
  }
}

let arr = [S()]

doSomething(arr) // error: cannot invoke 'doSomething' with an argument list of type '([S])’

--

My questions are twofold.

1. Is there any workaround to this issue that would let one declare a function that can take a collection whose element is anything that conforms to P, whether that be statically typed as P or its actual type, without either writing two versions of every API that takes a collection (and four versions of every API that takes two collections, eight versions of every API that takes three, etc.) or just giving up and accepting an array instead of a collection?

2. Are there any plans by the development team to address this issue?

Thanks,
Charles