0

I'd like to create a matrix where the element in the cell conforms to a protocol.

Here is kind of how I envision it being implemented, but I'm getting stuck in the syntax.

extension Array where Element == Array<T>, where T: MyProtocol {

}
5
  • As a courtesy and to help the community, if you downvote, please provide a reason why. Commented Dec 3, 2020 at 0:30
  • I just updated this other question to be named more accurately. It's your question, phrased differently, and so unfortunately, it has the same solution. Cannot extend generic type where placeholder is another generic type Commented Dec 3, 2020 at 0:38
  • Thank you Jessy. I think a nested type with a generic type is materially different from a generic type that has a generic type that conforms to a protocol. I think both will definitely have different incompatible answers as well. @Leo, what do you think? Commented Dec 3, 2020 at 1:25
  • Totally different questions. You don't need a generic method here Commented Dec 3, 2020 at 1:38
  • You are both wrong (Leo's answer doesn't cover Array, and Scotty's thinking is incorrect—the inability to refer to the placeholder is the limiting factor), but I'm welcome to be proven wrong myself. Add an answer if you have better than what I posted in the other Q&A. Commented Dec 3, 2020 at 3:47

2 Answers 2

3

You can constrain your Collection's Element to Collection and constrain its Element.Element to your protocol:

protocol MyProtocol { }
extension Collection where Element: Collection, Element.Element: MyProtocol {

}
Sign up to request clarification or add additional context in comments.

2 Comments

Both the matrix, and its elements need to be subscriptable for the method I'm making.
Just use RandomAccessCollection instead. If you need access to methods like insert, remove, append, etc... you will need to constrain it to RangeReplaceableCollection.
0

The generalized form of your question is, "How can I extend a generic type which has a placeholder that is also a generic type?". (The protocol part is not actually a part of your problem.)

The answer, as I showed in the other question I linked you to, is that you can't do it at the extension level. You have to do it at the method/subscript/initializer level.

It doesn't matter if the placeholder is replaced by the extended type, or not. Regardless, there's never a way to refer to a placeholder of a placeholder, in an extension declaration.

struct GenericType<PlaceHolder> { }

extension Array {
  func ƒ<🤷>() where Element == GenericType<🤷> { }

   subscript<🪆>(_: 🪆.Type = 🪆.self) -> Void
   where Element == Array<🪆> {
     get { }
   }
}

extension GenericType {
   init?<🧃>() where PlaceHolder == [🧃] {
     nil
   }
}

If you need a property, then you'll need to use at least one protocol, as Leo shows in his answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.