jhurray
jhurray

Reputation: 81

Swift 2.0 protocol extensions - typealias

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

Answers (3)

Milos
Milos

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

findall
findall

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

Austin
Austin

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

Related Questions