Range<T>.mapRange<U> -> Range<U>

(Karl) #1

I’d like to propose we add a function to Range<T> which allows transforming its bounds (both bounds, by the same transform). This would come in handy in many situations involving type conversions or bounds mutations:

// duplicated on CountableRange
extension Range {
  func mapRange<T: Comparable>(_ transform: (Bound) throws -> T) rethrows -> Range<T> {
    return try transform(lowerBound)..<(try transform(upperBound))

// Type conversion:
(myWrappedVal..<myOtherWrappedVal).mapRange { $0.sourceValue }
// Shifting:
(5..<15).mapRange { $0 + offset }

Is there some reason why this would not be desirable? It’s a convenience addition, sure, but it is very convenient if you use generic code with lots of Ranges and wrapping abstractions.

- Karl