Equality for generic container and Void

Is it possible now (with conditional conformances) to write a generic container, say Result<T>, that would be Equatable both when T: Equatable and T == Void? The obvious solution leads to overlapping conformances:

enum Result<T> {
    case success(T)
    case failure
}

extension Result: Equatable where T: Equatable { … }
extension Result: Equatable where T == Void { … }

I know I can make my own “placeholder” type like enum Unit: Equatable { case unit }, but that feels like a hack and has to be explained to other people reading the code.

Wouldn’t it make sense for Void (alias ()) to be Equatable? (Does this require solving the issue of protocol conformances for non-nominal types?)

Yes, it’s been a longstanding goal to have tuples of Equatable values conform to Equatable (currently, there’s a hack to implement == up to arity 6). We are held back because tuples cannot conform to protocols. Likewise, () would naturally conform to Equatable if it could. With time, I think, it’s certain that this will be addressed.

5 Likes

I remember adding my own unit type to a project too. I later removed it for the same reason, it’s just confusing. I wonder why Void in Swift is an empty tuple instead of say an empty struct or an enum with a single case. Anybody knows?

IIRC in ancient times, before Swift went public and open source, tuples where more fundamential to the language. Function arguments were tuples and an empty argument list was therefore an empty tuple. A function was a named closure that takes in a tuple as its argument and returns a tuple foo () -> (). An empty tuple then is naturaly the Void type.

Perhaps some of the ‘old’ gurus can clarify.

Terms of Service

Privacy Policy

Cookie Policy