Logically, your extension should work by multiplying an array of homogenous floating-point types with a value of the same type, and returning an array of that type. You can simply express this with an argument of type Element
, and a return of [Element]
:
// this could also just be an extension of Sequence
extension Array where Element : FloatingPoint {
public func multiply(by factor: Element) -> [Element] {
return self.map { $0 * factor }
}
}
Therefore for a [Float]
, this would accept an argument of type Float
and return a [Float]
.
However, what if I indeed want to return an array of Double
?
I do not believe it's possible to construct a Double
from an arbitrary FloatingPoint
(or even BinaryFloatingPoint
) conforming instance, as neither protocol (although they do require implementation of various aspects of the IEEE 754 specification) actually defines the precise encoding of the conforming type.
However, if you really want this, you could just write two overloads – one for Float
elements and one for Double
elements:
extension Sequence where Iterator.Element == Float {
public func multiply(by factor: Double) -> [Double] {
return self.map { Double($0) * factor }
}
}
extension Sequence where Iterator.Element == Double {
public func multiply(by factor: Double) -> [Double] {
return self.map { $0 * factor }
}
}
Alternatively, if you plan on making this work with a broader range of types, you can use a protocol
in order to define a requirement that allows conforming types to express their value as a Double
:
protocol ConvertibleToDouble {
func _asDouble() -> Double
}
extension Float : ConvertibleToDouble {
func _asDouble() -> Double { return Double(self) }
}
extension Double : ConvertibleToDouble {
func _asDouble() -> Double { return self }
}
extension Sequence where Iterator.Element : ConvertibleToDouble {
func multiply(by factor: Double) -> [Double] {
return self.map { $0._asDouble() * factor }
}
}