I'm creating a custom exponent operator and I tried using a generic type that conforms to the numeric protocol. However, it doesn't work. Numeric seems to be very restrictive about what it supports.
precedencegroup Exponentiative {
associativity: left
higherThan: MultiplicationPrecedence
}
infix operator ** : Exponentiative
public func ** <N: Numeric>(base: N, power: N) -> N {
return N.self( pow(Double(base), Double(power)) )
}
Instead I have to do this:
public func ** <N: BinaryInteger>(base: N, power: N) -> N {
return N.self( pow(Double(base), Double(power)) )
}
public func ** <N: BinaryFloatingPoint>(base: N, power: N) -> N {
return N.self( pow(Double(base), Double(power)) )
}
This is fine for short functions, but one could imagine having to write a much longer function than this.
How do I create a generic type that can accept any BinaryInteger
or BinaryFloatingPoint
?
I there any way to combine these functions into just one? This code duplication seems unnecessary.
This post is NOT a duplicate of Is there a way to convert any generic Numeric into a Double?
The first answer, when applied to my problem, would make the function even more redundant:
func f<T:Numeric>(_ i: T) {
var d: Double
switch i {
case let ii as Int:
d = Double(ii)
case let ii as Int8:
d = Double(ii)
case let ii as UInt8:
d = Double(ii)
case let ii as Int16:
d = Double(ii)
case let ii as UInt16:
d = Double(ii)
case let ii as Int32:
d = Double(ii)
case let ii as UInt32:
d = Double(ii)
case let ii as Int64:
d = Double(ii)
case let ii as UInt64:
d = Double(ii)
case let ii as Double:
d = ii
case let ii as Float32:
d = Double(ii)
case let ii as Float64:
d = Double(ii)
case let ii as Float:
d = Double(ii)
default:
fatalError("oops")
}
print(d)
}
Also, this switch statement would have to be applied to each argument passed to the function, which means the switch statement would have to be extracted into its own function.
The second answer in the above post is basically the same as the functions in my original post, so it does not answer my question either.
My post has absolutely NOTHING to do with this post: Making my function calculate average of array Swift.