I'm learning Swift coming from other languages with powerful type systems and I am wondering if their is any way to make a protocol conditionally conform to another protocol.
Let's take an example: I define a ShowableAsInt protocol, that allows to get an Int representation for any type that conforms to it.
protocol ShowableAsInt {
func intRepr() -> Int
}
extension Int : ShowableAsInt {
func intRepr() -> Int {
return self
}
}
extension String : ShowableAsInt {
func intRepr() -> Int {
return self.count
}
}
func show(_ s: ShowableAsInt) {
print(s.intRepr())
}
show("abc") // "3"
show(42) // "42"
Now I define a Container protocol that simply wraps an element.
protocol Container {
associatedtype T
var element: T {
get
}
}
struct StringContainer : Container {
typealias T = String
let element: String
}
struct IntContainer : Container {
typealias T = Int
let element: Int
}
Because Container is a simple wrapper, whenever the wrapped type can be shown as an Int, the container can also be shown as an Int. I tried to express this, but failed:
// Doesn't compile: can't extend a protocol to conform to another one?
extension Container : ShowableAsInt where T : ShowableAsInt {
func intRepr() -> Int {
return element.intRepr()
}
}
// I would like these to compile
show(IntContainer(42)) // "42"
show(StringContainer("abc")) // "3"
I know that this conditional conformance can be expressed on class and struct. Is there any way to do the same for protocols? If not, is there any reason for this restriction?