File: 0026-rdar21382194.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (114 lines) | stat: -rw-r--r-- 2,909 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// 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