can we express "does not conform to a particular protocol"?


(David Baraff) #1

I’m searching for the simplest way to write a function
  func maybeEqual<T>(_ lhs:T, _rhs:T) -> Bool

where it returns lhs == rhs if T is equatable, and false, otherwise.
I tried

func maybeEqual<T>(_ lhs:T, _rhs:T) -> Bool {
    return false
}

func maybeEqual<T:Equatable>(_ lhs:T, _ rhs:T) -> Bool {
    return lhs == rhs
}

but that doesn’t work. Is there a way to express a type not matching something?
Alternately, how can I write this?


(Austin Zheng) #2

I'm pretty sure solutions like the one you proposed are impossible, unfortunately :(. The compiler has to choose the static override at compile time, but it can't tell until runtime whether the type conforms to `Equatable` or not (because of retroactive conformance).

It's also not possible to use the as or is dynamic casting machinery to work with `Equatable`, because of the use of the `Self` type in its requirements.

A feature that the community has expressed interest in, "generalized existentials", may allow you to implement a function that does what you want.

Best,
Austin

···

On Jul 3, 2017, at 5:00 PM, David Baraff via swift-users <swift-users@swift.org> wrote:

I’m searching for the simplest way to write a function
  func maybeEqual<T>(_ lhs:T, _rhs:T) -> Bool

where it returns lhs == rhs if T is equatable, and false, otherwise.
I tried

func maybeEqual<T>(_ lhs:T, _rhs:T) -> Bool {
    return false
}

func maybeEqual<T:Equatable>(_ lhs:T, _ rhs:T) -> Bool {
    return lhs == rhs
}

but that doesn’t work. Is there a way to express a type not matching something?
Alternately, how can I write this?

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


(Zhao Xin) #3

You mean `type(of:lhs) == type(of:rhs)`?

Zhao Xin

···

On Tue, Jul 4, 2017 at 8:00 AM, David Baraff via swift-users < swift-users@swift.org> wrote:

I’m searching for the simplest way to write a function
func maybeEqual<T>(_ lhs:T, _rhs:T) -> Bool

where it returns lhs == rhs if T is equatable, and false, otherwise.
I tried

func maybeEqual<T>(_ lhs:T, _rhs:T) -> Bool {
    return false
}

func maybeEqual<T:Equatable>(_ lhs:T, _ rhs:T) -> Bool {
    return lhs == rhs
}

but that doesn’t work. Is there a way to express a type not matching
something?
Alternately, how can I write this?

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


(David Baraff) #4

No, i want the equality function run if the two types are equatable, and false otherwise (even if you might deem them to be the same, e.g. two identical sets, because sets do not conform to equatable, or two identical classes, becauses classes are not (in general) equatable).

So
  maybeEqual(3, 3) // true
  maybeEqual(3, 4) // false
  maybeEqual([1,2,3], [1,2,3]) // false (because arrays are not actual equatable)

  let d = [String:Any]()
  maybeEqual(d, d) // false because type(d) is not equatable even though obviously d is equal to itself


(Zhao Xin) #5

In my own test, it seams that there is no way to test a type conforms to
Equatable or not.

`Protocol 'Equatable' can only be used as a generic constraint because it
has Self or associated type requirements`

Zhao Xin

···

On Tue, Jul 4, 2017 at 9:27 AM, David Baraff <davidbaraff@gmail.com> wrote:

No, i want the equality function run if the two types are equatable, and
false otherwise (even if you might deem them to be the same, e.g. two
identical sets, because sets do not conform to equatable, or two identical
classes, becauses classes are not (in general) equatable).

So
  maybeEqual(3, 3) // true
  maybeEqual(3, 4) // false
  maybeEqual([1,2,3], [1,2,3]) // false (because arrays are not actual
equatable)

  let d = [String:Any]()
  maybeEqual(d, d) // false because type(d) is not equatable even
though obviously d is equal to itself