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?