Robert
Robert

Reputation: 5859

Conforming Array to Equatable for certain non-equatable types

Note: I think people are missing the point of this question, it's not about me having an array where the element is a protocol, and it's probably not even about conditionally conforming something to Equatable specifically; these are just the examples I'm using. The problem is that it doesn't seem to be possible to conditionally-conform something to a protocol multiple times (with different conditions).


When Swift 4.1 was announced with conditional conformance, I was looking forward to having arrays and dictionaries conform to Equatable when their elements did. In addition, I have some arrays of a custom protocol (called AnyDataType) which defines its own comparison function to allow comparing between any two AnyDataType variables, even if they're of different concrete types:

protocol AnyDataType {
    func isEqual(to otherDataType: AnyDataType) -> Bool
}

I was hoping I might make Array<AnyDataType> conform to Equatable by adding an additional conformance:

extension Array: Equatable where Element == AnyDataType {
    static func == (lhs: [AnyDataType], rhs: [AnyDataType]) -> Bool {
        ...
    }
}

Unfortunately, it doesn't work. While it does compile, I get the following warning:

Conformance of 'Array' to protocol 'Equatable' was already stated in the type's module 'Swift'

And it doesn't actually make Array<AnyDataType> conform to Equatable anyway (e.g. you can't compare two [[AnyDataType]]s). Is there anything different I need to do, or is this just not possible?


Note that this has nothing to do with it being an array of protocols. I had the same problems trying to conform an array of custom, non-Equatable structs as well.

Upvotes: 0

Views: 1397

Answers (2)

Robert
Robert

Reputation: 5859

It turns out that this is an intended restriction, according to SE-0143, but it might be something which is allowed in the future.

For now, depending on the desired usage, the best solutions are probably:

  • If you wanted to conform to Equatable so that == would work, you can just implement the == on the specialised collections directly without the conformance (and add an implementation for != which just negates that result). This is satisfactory for me for the time being.
  • If you wanted to have collections of your type actually conform to Equatable where the type itself can't (because it's e.g. a protocol), type erasure might be an option.

Upvotes: 3

Avi
Avi

Reputation: 7552

There's no way to do accomplish what you want.

Upvotes: -2

Related Questions