Swift: Making Tuples Equatable
Lots of copypasta
Until we get a first-class macro system, this involves a lot of copypasta, but it does work:
@infix func == <T:Equatable> (lhs: (T), rhs: (T)) -> Bool {
return lhs.0 == rhs.0
}
@infix func == <T:Equatable, T2:Equatable> (lhs: (T,T2), rhs: (T,T2)) -> Bool {
return lhs.0 == rhs.0 &&
lhs.1 == rhs.1
}
@infix func == <T:Equatable, T2:Equatable, T3:Equatable> (lhs: (T,T2,T3), rhs: (T,T2,T3)) -> Bool {
return lhs.0 == rhs.0 &&
lhs.1 == rhs.1 &&
lhs.2 == rhs.2
}
@infix func == <T:Equatable, T2:Equatable, T3:Equatable, T4:Equatable> (lhs: (T,T2,T3,T4), rhs: (T,T2,T3,T4)) -> Bool {
return lhs.0 == rhs.0 &&
lhs.1 == rhs.1 &&
lhs.2 == rhs.2 &&
lhs.3 == rhs.3
}
@infix func == <T:Equatable, T2:Equatable, T3:Equatable, T4:Equatable, T5:Equatable> (lhs: (T,T2,T3,T4, T5), rhs: (T,T2,T3,T4, T5)) -> Bool {
return lhs.0 == rhs.0 &&
lhs.1 == rhs.1 &&
lhs.2 == rhs.2 &&
lhs.3 == rhs.3 &&
lhs.4 == rhs.4
}
Now we can do this:
func test<T:Equatable,K:Equatable,V:Equatable>(a:(T,K,V), b:(T,K,V)) {
let v = a == b
}
let t1 = (1, 2, "a")
let t2 = (1, 2, "b")
test(t1, t2)
I'll be throwing the code up on github soon, along with all the other little bits I've collected.
I tried to extend it to support tuples without constraining all the types to equatable, since it would be nice to avoid having to specify the Equatable
constraint over and over, but that led to rdar://17420860
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: swift frontend command failed due to signal (use -v to see invocation)
Command usr/bin/swift failed with exit code 254
Fair warning, if you paste this code into a Swift file, not only will builds fail with a hard crash of the Swift compiler, but Xcode's SourceKit will die too. Repeatedly. Continuously.
@infix func == <T, T2, T3> (lhs: (T,T2,T3), rhs: (T,T2,T3)) -> Bool {
return lhs.0 as Equatable == rhs.0 as Equatable &&
lhs.1 as Equatable == rhs.1 as Equatable &&
lhs.2 as Equatable == rhs.2 as Equatable
}
I'm working on a feature request to support promoting a given tuple to Equatable
if all its elements are Equatable
; it would be very handy for some of the work I'm doing to support arbitrary tuples in a generic way (I ultimately don't care how many elements there are, I just care that they all satisfy the Equatable
constraint). If I could get a tuple's length and iterate over its items then I could treat it almost like an Any[]
.
This blog represents my own personal opinion and is not endorsed by my employer.