Introducing an “Unwrap or Throw” operator

Recently, someone pointed out to me that, if you squint a lot, Optional is just Result where Failure is nil kind of thing. Given this, the "correct" function to use would be try get().

Using the following generic conversion functions foo! is equivalent to try! foo.get() with try? foo.get() being a full round trip.

public extension Optional {
    enum UnwrappingError : Error {
        case foundNilWhileUnwrappingAnOptionalValue
    }
    
    func get(orThrow error: @autoclosure () -> Error = UnwrappingError.foundNilWhileUnwrappingAnOptionalValue) throws -> Wrapped {
        if let value = self {
            return value
        } else {
            throw error()
        }
    }
}

public extension Result {
    init(_ optional: Success?, failure: @autoclosure () -> Failure) {
        if let success = optional {
            self = .success(success)
        } else {
            self = .failure(failure())
        }
    }
}

public extension Result where Failure == Error {
    init(_ optional: Success?) {
        self = Result {
            try optional.get()
        }
    }
}