Thanks for the response Slava. What stops the compiler from checking if a type is not allowed to retroactively conform to a protocol? For example, we provide the constraint that any type conforming to protocol A can't also conform to protocol B. If we create a type T: A and extend it later to conform to B, why can't the compiler raise an error at that point?
How about this. You can take advantage of the fact that a type can only (non-retroactively) conform to a protocol once with one associated type binding to do something like this
protocol ThreeCycle {
associatedtype Beats: ThreeCycle where Beats.Beats.Beats == Self
associatedtype BeatMarker
}
protocol RockType: ThreeCycle where Beats: ScissorType, BeatMarker == any ScissorType { }
protocol ScissorType: ThreeCycle where Beats: PaperType, BeatMarker == any PaperType { }
protocol PaperType: ThreeCycle where Beats: RockType, BeatMarker == any RockType { }
The same-type constraints on the BeatMarker associated type make it impossible for one conformance to satisfy more than one of the RockType, ScissorType, or PaperType protocol requirements.
Thanks for your response Joe! That's a great answer. It also gives a way to create an XOR between protocols
protocol XOR {
associatedtype Marker
}
protocol A: XOR where Marker == any A {
func doThis()
}
protocol B: XOR where Marker == any B {
func doThat()
}
struct Both: A, B { //Type 'Both' does not conform to protocol 'A', 'B' or 'Exclude'
func doThis() {}
func doThat() {}
}