Skip to content

Instantly share code, notes, and snippets.

struct Vector<A> {
let fst: A
let snd: A
}
extension Vector: CustomStringConvertible where A: CustomStringConvertible {
var description: String {
return "Vector<\(String(describing: A.self))>(\(fst.description), \(snd.description))"
}
}
infix operator ◊: MultiplicationPrecedence
/// Protocol for scalar multiplication operation
protocol Scalar {
associatedtype ScalarVal
static func ◊ (_ lhs: ScalarVal, _ rhs: Self) -> Self
}
extension Additive where Self: TwoDimensions, Self.ComponentVal: Additive {
static var addId: Self {
return Self.make2D(Self.ComponentVal.addId, Self.ComponentVal.addId)
}
static func + (lhs: Self, rhs: Self) -> Self {
return make2D(lhs.fst + rhs.fst, lhs.snd + rhs.snd)
}
}
/// A protocol for getting the magnitude of an object
protocol Magnitude {
associatedtype MagVal: Comparable
var magSquare: MagVal { get }
}
extension Magnitude where
Self: TwoDimensions,
Self.ComponentVal: Multiplicative,
Self.ComponentVal: Additive,
Self.ComponentVal == Self.MagVal {
var magSquare: Self.MagVal {
return self.fst * self.fst + self.snd * self.snd
}
}
/// Protocol for multiplication with identity
protocol Multiplicative {
static var multId: Self { get }
static func * (_ lhs: Self, _ rhs: Self) -> Self
}
/// Protocol for 2D coordinate systems
protocol TwoDimensions {
associatedtype ComponentVal
static func make2D(_ fst: ComponentVal, _ snd: ComponentVal) -> Self
var fst: ComponentVal { get } // The first component
var snd: ComponentVal { get } // The second component
}
// Ints are Additive, the identity is 0
extension Int: Additive {
static var addId: Int { return 0 }
}
// Ints are Multiplicative, the identity is 1
extension Int: Multiplicative {
static var multId: Int {
return 1
}
}
/// Protocol for addition with identity
protocol Additive {
static var addId: Self { get }
static func + (_ lhs: Self, _ rhs: Self) -> Self
}