mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
115 lines
2.8 KiB
Swift
115 lines
2.8 KiB
Swift
// RUN: not %target-swift-frontend %s -typecheck
|
|
|
|
/// Abstraction of numeric types that approximate real numbers
|
|
protocol ApproximateReal {
|
|
init() // zero
|
|
func * (Self,Self) -> Self
|
|
func + (Self,Self) -> Self
|
|
func / (Self,Self) -> Self
|
|
func - (Self,Self) -> Self
|
|
prefix func + (Self) -> Self
|
|
prefix func - (Self) -> Self
|
|
}
|
|
|
|
extension Double : ApproximateReal {}
|
|
extension Float : ApproximateReal {}
|
|
|
|
// Abstraction of a mathematical vector
|
|
protocol Vector {
|
|
init()
|
|
associatedtype Element : ApproximateReal
|
|
func dotProduct(Self) -> Element
|
|
|
|
|
|
// Extras
|
|
var count: Int {get}
|
|
subscript(Int) -> Element {get set}
|
|
associatedtype Tail
|
|
}
|
|
|
|
struct EmptyVector<T: ApproximateReal> : Vector {
|
|
init() {}
|
|
typealias Element = T
|
|
func dotProduct(other: EmptyVector) -> Element {
|
|
return Element() // zero
|
|
}
|
|
var count: Int { return 0 }
|
|
|
|
subscript(i: Int) -> Element {
|
|
get { fatalError("subscript out-of-range") }
|
|
set { fatalError("subscript out-of-range") }
|
|
}
|
|
}
|
|
|
|
struct Vector<Tail: Vector> : Vector {
|
|
typealias Element = Tail.Element
|
|
|
|
init(head: Element, tail: Tail) {
|
|
self.head = head
|
|
self.tail = tail
|
|
}
|
|
|
|
init() {
|
|
self.head = Element()
|
|
self.tail = Tail()
|
|
}
|
|
|
|
/*
|
|
init(scalar: Element) {
|
|
self.head = Element()
|
|
self.tail = Tail()
|
|
}
|
|
*/
|
|
|
|
func dotProduct(other: Vector) -> Element {
|
|
return head * other.head + tail.dotProduct(other.tail)
|
|
}
|
|
|
|
var count: Int { return tail.count + 1 }
|
|
var head: Element
|
|
var tail: Tail
|
|
|
|
subscript(i: Int) -> Element {
|
|
get { return i == 0 ? head : tail[i - 1] }
|
|
set { if i == 0 { head = newValue } else { tail[i - 1] = newValue } }
|
|
}
|
|
}
|
|
|
|
extension Vector where Tail == EmptyVector<Element> {
|
|
init(_ scalar: Element) {
|
|
self.init()
|
|
self[0] = scalar
|
|
}
|
|
}
|
|
|
|
//===--- A nice operator for composing vectors ----------------------------===//
|
|
//===--- there's probably a more appropriate symbol -----------------------===//
|
|
infix operator ⋮ {
|
|
associativity right
|
|
precedence 1
|
|
}
|
|
|
|
func ⋮ <T: ApproximateReal> (lhs: T, rhs: T) -> Vector<Vector<EmptyVector<T> > > {
|
|
return Vector(head: lhs, tail: Vector(head: rhs, tail: EmptyVector()))
|
|
}
|
|
func ⋮ <T: ApproximateReal, U where U.Element == T> (lhs: T, rhs: Vector<U>) -> Vector<Vector<U> > {
|
|
return Vector(head: lhs, tail: rhs)
|
|
}
|
|
|
|
extension Vector : CustomDebugStringConvertible {
|
|
var debugDescription: String {
|
|
if count == 1 {
|
|
return "Vector(\(String(reflecting: head)))"
|
|
}
|
|
return "\(String(reflecting: head)) ⋮ " + (count == 2 ? String(reflecting: self[1]) : String(reflecting: tail))
|
|
}
|
|
}
|
|
|
|
//===--- Test -------------------------------------------------------------===//
|
|
print(Vector(head: 3.0, tail: EmptyVector()))
|
|
print(3.0 ⋮ 4.0 ⋮ 5.0)
|
|
print( (3.0 ⋮ 4.0 ⋮ 5.0).dotProduct(6.0 ⋮ 7.0 ⋮ 8.0) ) // 86.0
|
|
|
|
// print( (3.0 ⋮ 4.0 ⋮ 5.0).dotProduct(6.0 ⋮ 7.0) ) // Won't compile
|
|
|