I have a plain Result
type:
public enum Result<T> {
case success(T)
case error
}
I want to make the type Equatable
, easy enough:
public enum Result<T: Equatable>: Equatable {
case success(T)
case error
// definition of ==
}
But then I want to use Result<Void>
, and that’s a type error since Void
doesn’t conform to Equatable
. Is there a way to define a Result
type that would conform to Equatable
, accept Result<Void>
and still use the correct equality check for T: Equatable
? Wouldn’t it make sense for Void
to implement Equatable
?
I don't think that is possible at present. Void
is the type of the
empty tuple ()
, and tuples cannot adopt protocols (a discussion about
that topic starts at [swift-evolution] Synthesizing Equatable, Hashable, and Comparable for tuple types).
A possible workaround (as suggested by @Hamish above) is to use a custom
type instead of Void
:
struct Unit: Equatable {
static var unit = Unit()
public static func ==(lhs: Unit, rhs: Unit) -> Bool {
return true
}
}
let res = Result.success(Unit.unit)
I initially though that once SE-0143 Conditional conformances is implemented then one could define
public enum Result<T> {
case success(T)
case error
}
public extension Result: Equatable where T: Equatable {
public static func ==(lhs: Result, rhs: Result) -> Bool {
// ...
}
}
public extension Result: Equatable where T == Void {
public static func ==(lhs: Result, rhs: Result) -> Bool {
return true
}
}
without the need the make Void
itself Equatable
.
However (again attribution goes to @Hamish) this won't work because multiple conformances won't be permitted.