What about taking a mathematical approach to numbers? protocol Group : Equatable { static var zero: Self { get } static func + (Self, Self) -> Self static func += (inout Self, Self) static func - (Self, Self) -> Self static func -= (inout Self, Self) static prefix func - (Self) -> Self }
protocol Ring : Group { static var one: Self { get } static func * (Self, Self) -> Self static func *= (inout Self, Self) func tryDivide(by: Self) -> Self? func tryInvert() -> Self? } protocol Field : Ring { static func / (Self, Self) -> Self static func /= (inout Self, Self) var inverted: Self { get } } protocol VectorSpace : Group { associatedtype Scalar : Field static func * (Self, Scalar) -> Self static func *= (inout Self, Scalar) -> Self static func / (Self, Scalar) -> Self static func /= (inout Self, Scalar) -> Self static func * (Scalar, Self) -> Self } Detalization of mathematical terminology will be determined by what kind of types we have in the standard library. Integer types are rings (except for overflow), floating-point types are fields (except for precision), point types are linear spaces, so I thought the abstractions above are the bare minimum. Unfortunately, Swift doesn’t have rename operations for protocol requirements, so we can’t express groups that use operations other than + and -. What we can do is to include an adapter to wrap current instance in an additive group interface: struct MultiplicativeGroupAdapter<T: Field> : Group { // ... } extension Field { var multiplicativeGroup: MultiplicativeGroupAdapter<Self> }
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution