Not necessarily.
struct Void {
init() {}
}
struct Tuple<First, Rest> {
var first: First
var rest: Rest
}
Then make ()
sugar for Void
, (T, U)
sugar for Tuple<T, U>
, (T, U, V)
sugar for Tuple<T, Tuple<U, V>>
, etc. This design lends itself to recursive definitions of protocol conformances:
extension Void: Equatable {
static func == (lhs: Void, rhs: Void) -> Bool {
return true
}
}
extension Tuple: Equatable where First: Equatable, Rest: Equatable {
static func == (lhs: Tuple, rhs: Tuple) -> Bool {
return lhs.first == rhs.first && lhs.rest == rhs.rest
}
}