Best way to solve ambiguous references to methods


(Vinicius Vendramini) #1

So I was playing around with Sequences, and I came across a problem I haven't been able to solve in a decent way. I’ve reduced it to a simpler example here:

let array : [Int] = [1, 2, 3]

let mapArray = array.map { $0 }

let flatArray = mapArray.flatten() // Error!

This last line of code prints the following error:

let flatArray = mapArray.flatten() // Error!
                ^~~~~~~~
Swift.SequenceType:4:17: note: found this candidate
    public func flatten() -> FlattenSequence<Self>
                ^
Swift.CollectionType:4:17: note: found this candidate
    public func flatten() -> FlattenCollection<Self>
                ^
Swift.CollectionType:4:17: note: found this candidate
    public func flatten() -> FlattenBidirectionalCollection<Self>
                ^

As far as I understand it, the error happens because several protocols extensions implement the `flatten` method, and `mapArray` (which is of type `Array<Optional<Int>>`) conforms to a few of those, which means the compiler has no way of knowing which one I intend on using.

How do I solve this?


(Harlan Haskins) #2

A quick-and-dirty way would be to explicitly cast to the protocol type before calling the function.

let flatArray = (mapArray as SequenceType).flatten()

Or in this case you could just mapArray.flatMap()

···

On Dec 5, 2015, at 12:38 PM, Vinicius Vendramini <vinivendra@gmail.com> wrote:

So I was playing around with Sequences, and I came across a problem I haven't been able to solve in a decent way. I’ve reduced it to a simpler example here:

let array : [Int] = [1, 2, 3]

let mapArray = array.map { $0 }

let flatArray = mapArray.flatten() // Error!

This last line of code prints the following error:

let flatArray = mapArray.flatten() // Error!
                ^~~~~~~~
Swift.SequenceType:4:17: note: found this candidate
    public func flatten() -> FlattenSequence<Self>
                ^
Swift.CollectionType:4:17: note: found this candidate
    public func flatten() -> FlattenCollection<Self>
                ^
Swift.CollectionType:4:17: note: found this candidate
    public func flatten() -> FlattenBidirectionalCollection<Self>
                ^

As far as I understand it, the error happens because several protocols extensions implement the `flatten` method, and `mapArray` (which is of type `Array<Optional<Int>>`) conforms to a few of those, which means the compiler has no way of knowing which one I intend on using.

How do I solve this?

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Vinicius Vendramini) #3

(I should mention I’m trying this in a Playground.)

I think I tried a similar solution at some point, but it doesn’t seem to work. I get two errors out of that cast:

Playground execution failed: /var/folders/1v/42yjnyj16bb16j19q25hzghr0000gn/T/./lldb/13003/playground346.swift:168:27: error: member 'flatten' cannot be used on value of protocol type 'SequenceType'; use a generic constraint instead
let flatArray = (mapArray as SequenceType).flatten() // Error!
                ~~~~~~~~~~^~~~~~~~~~~~~~~~ ~~~~~~~
/var/folders/1v/42yjnyj16bb16j19q25hzghr0000gn/T/./lldb/13003/playground346.swift:168:30: error: protocol 'SequenceType' can only be used as a generic constraint because it has Self or associated type requirements
let flatArray = (mapArray as SequenceType).flatten() // Error!
                             ^

I can’t seem to find a way to cast it to something that works.

As for the flatMap, I know it’s a valid alternative, but I was trying to make this work just for the understanding you get through exploration of these weird cases.

···

On Dec 5, 2015, at 12:43 PM, Harlan Haskins <harlan@harlanhaskins.com> wrote:

A quick-and-dirty way would be to explicitly cast to the protocol type before calling the function.

let flatArray = (mapArray as SequenceType).flatten()

Or in this case you could just mapArray.flatMap()

On Dec 5, 2015, at 12:38 PM, Vinicius Vendramini <vinivendra@gmail.com <mailto:vinivendra@gmail.com>> wrote:

So I was playing around with Sequences, and I came across a problem I haven't been able to solve in a decent way. I’ve reduced it to a simpler example here:

let array : [Int] = [1, 2, 3]

let mapArray = array.map { $0 }

let flatArray = mapArray.flatten() // Error!

This last line of code prints the following error:

let flatArray = mapArray.flatten() // Error!
                ^~~~~~~~
Swift.SequenceType:4:17: note: found this candidate
    public func flatten() -> FlattenSequence<Self>
                ^
Swift.CollectionType:4:17: note: found this candidate
    public func flatten() -> FlattenCollection<Self>
                ^
Swift.CollectionType:4:17: note: found this candidate
    public func flatten() -> FlattenBidirectionalCollection<Self>
                ^

As far as I understand it, the error happens because several protocols extensions implement the `flatten` method, and `mapArray` (which is of type `Array<Optional<Int>>`) conforms to a few of those, which means the compiler has no way of knowing which one I intend on using.

How do I solve this?

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users