Optimal custom operator with generic type constraint for numerical type I'm implementing (for an article) two custom infix operators:


¿% - to calculate percent of total
%? - to calculate the percent that represents a segment of total


After debugging some errors and looking for information I finally found a way to get my code working:

protocol NumericType {

    static func *(lhs: Self, rhs: Self) -&gt; Self
    static func *(lhs: Self, rhs: Int) -&gt; Self
    static func /(lhs: Self, rhs: Self) -&gt; Self
    static func /(lhs: Self, rhs: Int) -&gt; Self

} // NumericType

extension Double : NumericType {

    internal static func *(lhs: Double, rhs: Int) -&gt; Double {
        return lhs * Double(rhs)
    }

    internal static func /(lhs: Double, rhs: Int) -&gt; Double {
        return lhs / Double(rhs)
    }

 } // extension Double : NumericType

extension Float : NumericType {

    internal static func *(lhs: Float, rhs: Int) -&gt; Float {
        return lhs * Float(rhs)
    }

    internal static func /(lhs: Float, rhs: Int) -&gt; Float {
        return lhs / Float(rhs)
    }

 } // extension Float : NumericType

extension Int : NumericType { }

infix operator ¿%

func ¿% &lt;T: NumericType&gt;(percentage: T, ofThisTotalValue: T) -&gt; T {

    return (percentage * ofThisTotalValue) / 100

} // infix operator ¿%

infix operator %?

func %? &lt;T: NumericType&gt;(segment: T, ofThisTotalValue: T) -&gt; T {

    return (segment * 100) / ofThisTotalValue

} // infix operator %?

let percentage: Double = 8
let price: Double = 45

let save = percentage ¿% price

print("\(percentage) % of \(price) $ = \(save) $")

print("\(save) $ of \(price) $ = \(save %? price) %")


The output:

8.0 % of 45.0 $ = 3.6 $
3.6 $ of 45.0 $ = 8.0 %


Do you thinks there could be a more optimal and readable approach? Could you give some advice or share an example?
I imagine that you started out with something like this: 

infix operator ¿%

func ¿% &lt;T: NumericType&gt;(percentage: T, ofTotal: Double) -&gt; Double {
    return percentage * ofTotal / 100.0
} 


And received the error: 


  binary operator '*' cannot be applied to operands of type 'T' and 'Double'


You've solved this by creating a function with signature NumericType * Double -&gt; Double... which works, but as you've found requires a bunch of boilerplate.

The alternative approach is to to find a way to convert NumericType to a double so that in the end you're doing the multiplication on two doubles:

(NumericType -&gt; Double) * Double - &gt; Double

An implementation of this would look something like this: 

protocol NumericType {
    var doubleValue: Double { get }
}

infix operator ¿%
infix operator %?

func ¿% &lt;T: NumericType&gt;(percentage: T, ofTotal: Double) -&gt; Double {
    return percentage.doubleValue * ofTotal / 100.0
}

func %? &lt;T: NumericType&gt;(segment: T, ofTotal: Double) -&gt; Double {
    return segment.doubleValue * 100 / ofTotal
}

extension Double: NumericType {
    var doubleValue: Double { return self }
}

extension Int: NumericType {
    var doubleValue: Double { return Double(self) }
}


However, please please please reconsider using custom operators like this. 

I don't think that it's improving the readability or maintainability of your code, and unless you're using it every single day, I feel like it's something that will cause headaches in the future.