No luck with extending tuples

First, I wrote this:

// transpose a tuple
//
let tr = {(u:(Int, Int)) -> (Int, Int) in
    (u.1, u.0)
}

No problems there, all good. :smile:

Then I got very excited and thought I could do much better than that, and I wrote this:

extension (Int, Int) {
   var tr : Self {
       (self.1, self.0)
   }
}

Immediately, I got the error :

// Error: Non-nominal type '(Int, Int)' cannot be extended

And then I tried this:

typealias Tuple = (Int, Int)

extension Tuple {
   var tr : Self {
       (self.1, self.0)
   }
}

Still, no luck:

// Error: Non-nominal type '(Int, Int)' cannot be extended

Would this ((Int, Int)) be a good candidate for inclusion in Swift's type system?

1 Like

Yep, all non-nominal types can't be extended at this point. You can read more here

1 Like

Until we can extend non-nominal types we can expose this in a form of functions:

func reversed<T>(_ a: (T, T)) -> (T, T) {
    (a.1, a.0)
}
func reversed<T>(_ a: (T, T, T)) -> (T, T, T) {
    (a.2, a.1, a.0)
}
// ... up to a reasonable number of arguments

// usage:
reversed((1, 2)) // (2, 1)

Whether to include this in a standard library I don't know. Show your use case?

Unless you created another wrapper to access tuple values by index,
func value<T>(_ a: (T, T), at index: Int) -> T {
    switch index {
    case 0: return a.0
    case 1: return a.1
    default: fatalError("index out of bounds")
    }
}

func setValue<T>(_ a: inout (T, T), _ value: T, at index: Int) {
    switch index {
    case 0: a.0 = value
    case 1: a.1 = value
    default: fatalError("index out of bounds")
    }
}

tuple indexes are compile time constants, which raises a question why prefer "let b = reversed(a); (b.0, b.1)" form over a mere "(a.1, a.0)"

2 Likes