Why is Equatable not defined for optional arrays

Update: Conditional conformance has been implemented in Swift 4.1. Arrays and optionals of Equatable elements are themselves
Equatable now, and your code

let a: [Int]? = [1]
let b: [Int]? = nil
a == b

compiles and works as expected in Xcode 9.3. The workarounds are not
needed anymore.


(Old answer:)
Optionals can be compared only if the underlying wrapped type is equatable:

public func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool

Now Arrays can be compared if the element type is equatable:

/// Returns true if these arrays contain the same elements.
public func ==<Element : Equatable>(lhs: [Element], rhs: [Element]) -> Bool

but even for equatable types T, Array<T> does not conform to the Equatable protocol.

At present, this is not possible in Swift, see for example
Why can’t I make Array conform to Equatable? for a discussion
in the Apple developer forum. This change with the implementation
of SE-0143 Conditional conformances
in Swift 4.

Your implementation looks correct, here is a possible different one
using switch/case with pattern matching:

func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool {

    switch (lhs, rhs) {
    case let (l?, r?) : // shortcut for (.Some(l), .Some(r))
        return l == r
    case (.None, .None):
        return true
    default:
        return false
    }
}

Leave a Comment