I've found Never very helpful when working with generic types. But its usefulness is limited by the fact that it doesn't conform to Equatable and Hashable. I'd like to add those conformances to the standard library.
Consider the following result type:
enum Result<Value, Error> {
case success(Value)
case failure(Error)
}
extension Result: Equatable where Value: Equatable, Error: Equatable {
static func == (lhs: Result, rhs: Result) -> Bool {
switch (lhs, rhs) {
case let (.success(lhs), .success(rhs)):
return lhs == rhs
case let (.failure(lhs), .failure(rhs)):
return lhs == rhs
case (.success, .failure), (.failure, .success):
return false
}
}
}
extension Result: Hashable where Value: Hashable, Error: Hashable {
var hashValue: Int {
switch self {
case let .success(value):
return value.hashValue
case let .failure(error):
return error.hashValue
}
}
}
The conditional conformances to Equatable and Hashable can be very useful for testing results or putting them in collections.
It's often also convenient to use Never to represent something that always succeeds (Result<_, Never>) or always fails (Result<Never, _>).
Unfortunately, those don't play well together. Either (1) Result needs to add 2 more Equatable and Hashable conformances for when values or errors are Never or (2) Never itself needs to be Equatable and Hashable.
This isn't unique to Result. I've run into this with other enums and even with classes that are generic over optional values.
Writing these conformances for Never is easy:
extension Never: Equatable {
public static func == (lhs: Never, rhs: Never) -> Bool {
switch (lhs, rhs) {
}
}
}
extension Never: Hashable {
public func hashValue: Int {
switch self {
}
}
}
But adding them yourself is problematic—especially if you're writing code in a shared library. So I'd like to add these conformances to the standard library.
(Ideally, these implementations could be synthesized by the compiler. But that's not possible today.)