Reputation: 81
I am trying to have a extend a protocol in the following way but I am getting the error: Cannot convert return expression of type typable to typable.
I thought by saying typalias MyType : inside
MyType will have to be an entity that conforms to inside
struct typeable<T> {
let value : String = "hello world"
}
protocol inside {
func __myFunction() -> typeable<inside>
}
protocol outside : inside {
typealias MyType : inside
func myFunction() -> typeable<MyType>
}
extension outside {
final func __myFunction() -> typeable<inside> {
return self.myFunction()
}
}
struct thing : outside {
typealias MyType = thing
func myFunction() -> typeable<thing> {
return typeable<thing>()
}
}
Upvotes: 1
Views: 650
Reputation: 2758
Your inside
protocol:
protocol inside {
func __myFunction() -> typeable<inside>
}
... requires a function with a return type typeable<inside>
, which is not the same as typeable<T>
where T: inside
. On the other hand, the default implementation of the conforming candidate function in the extension of outside
returns a typeable<MyType>
where MyType
has not been up-casted to inside
...
The following code, however, or some variant thereof, may express your intent (as far as I understand it) without tripping up the compiler:
struct Typeable<T> {
init(_: T) {}
}
extension Typeable : CustomStringConvertible {
var description: String { return "I'm a \(self.dynamicType)" }
}
protocol InsideType {
func asTypeableInside() -> Typeable<Self>
}
protocol OutsideType : InsideType {
func asTypeableOutside() -> Typeable<Self>
}
extension OutsideType {
func asTypeableInside() -> Typeable<Self> {
return asTypeableOutside()
}
}
struct Outside {}
extension Outside : OutsideType {
func asTypeableOutside() -> Typeable<Outside> {
return Typeable(self)
}
}
... with following properties:
let o = Outside()
let x = o.asTypeableOutside()
print( o ) // prints: Outside()
print( x ) // prints: I'm a Typeable<Outside>
o is InsideType // always true
x is Typeable<InsideType> // always false
Typeable(o) is Typeable<Outside> // always true
Typeable(o) is Typeable<OutsideType> // always false
Typeable(o) is Typeable<InsideType> // always false
... bearing in mind that:
5 is CustomStringConvertible // always true
Typeable(5) is Typeable<CustomStringConvertible> // always false
Upvotes: 1
Reputation: 2193
In the definition __myFunction
in the extension to outside
, the uninstantiated type MyType
can be of any type which inherits inside
, which may be instantiated anywhere outside
is implemented. So returning a typeable<inside>
as being of typeable<MyType>
simply proved to be type mismatch.
You, however, can avoid the error changing the definition a little bit.
struct typeable<T> {
let value : String = "hello world"
}
protocol inside {
typealias MyType
func __myFunction() -> typeable<MyType>
}
protocol outside : inside {
typealias MyType : inside
func myFunction() -> typeable<MyType>
}
extension outside {
final func __myFunction() -> typeable<MyType> {
return self.myFunction()
}
}
struct thing : outside {
typealias MyType = thing
func myFunction() -> typeable<thing> {
return typeable<thing>()
}
}
Upvotes: 0
Reputation: 1085
It doesn't appear that the typealias MyType : inside
within the outside
protocol is visible in the outside
extension. I was able to get the extension to compile by putting the typealias MyType = inside
(note the =
rather than :
), but that made the thing
struct error on compilation.
It's difficult to figure out what you're actually trying to do, more context would be helpful to fully grasp the problem at hand.
Upvotes: 0