6
6
** |/ **
7
7
\* */
8
8
9
-
10
-
11
9
package scala .math
12
10
13
11
import java .util .Comparator
14
12
15
13
/** A trait for representing total orderings. It is important to
16
14
* distinguish between a type that has a total order and a representation
17
- * of total ordering on some type. This trait is for representing the
18
- * latter.
15
+ * of total ordering on some type. This trait is for the latter.
16
+ *
17
+ * A [[http://en.wikipedia.org/wiki/Total_order|total ordering ]]
18
+ * is a binary relation on a type `T` that is also an equivalence relation
19
+ * and partial ordering on values of type `T`. This relation is exposed as
20
+ * the `compare` method of the `Ordering` trait.
19
21
*
20
- * A <a href="http://en.wikipedia.org/wiki/Total_order">total ordering</a>
21
- * is a binary relation on a type <code>T</code> that is also an equivalence relation
22
- * and partial ordering on values of type <code>T</code>. This relation is exposed as
23
- * the <code>compare</code> method of the <code>Ordering</code> trait.
24
22
* This relation must be:
25
- * <ul>
26
- * <li>reflexive: <code>compare(x, x) == 0</code>, for any <code>x</code> of
27
- * type <code>T</code>.</li>
28
- * <li>symmetry: <code>compare(x, y) == z</code> and <code>compare(y, x) == w</code>
29
- * then <code>math.signum(z) == -math.signum(w)</code>, for any <code>x</code> and <code>y</code> of
30
- * type <code>T</code> and <code>z</code> and <code>w</code> of type <code>Int</code>.</li>
31
- * <li>transitive: if <code>compare(x, y) == z</code> and <code>compare(y, w) == v</code>
32
- * and <code>math.signum(z) >= 0</code> and <code>math.signum(v) >= 0</code> then
33
- * <code>compare(x, w) == u</code> and <code>math.signum(z + v) == math.signum(u)</code>,
34
- * for any <code>x</code>, <code>y</code>,
35
- * and <code>w</code> of type <code>T</code> and <code>z</code>, <code>v</code>, and <code>u</code>
36
- * of type <code>Int</code>.</li>
37
- * </ul>
23
+ {{{
24
+ reflexive: x == x
25
+ antisymmetric: if x <= y && y <= x, then x == y
26
+ transitive: if x <= y && y <= z, then x <= z
27
+ }}}
38
28
*
39
29
* @author Geoffrey Washburn
40
30
* @version 0.9.5, 2008-04-15
@@ -46,36 +36,31 @@ trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializabl
46
36
/** An Ordering is defined at all x and y. */
47
37
def tryCompare (x : T , y : T ) = Some (compare(x, y))
48
38
49
- /** Returns a negative integer iff <code>x</code> comes before
50
- * <code>y</code> in the ordering, returns 0 iff <code>x</code>
51
- * is the same in the ordering as <code>y</code> , and returns a
52
- * positive number iff <code>x</code> comes after
53
- * <code>y</code> in the ordering.
39
+ /** Returns a negative integer iff `x` comes before
40
+ * `y` in the ordering, returns 0 iff `x`
41
+ * is the same in the ordering as `y` , and returns a
42
+ * positive number iff `x` comes after
43
+ * `y` in the ordering.
54
44
*/
55
45
def compare (x : T , y : T ): Int
56
46
57
- /** Returns <code>true</code> iff <code>x</code> comes before
58
- * <code>y</code> in the ordering.
47
+ /** @return true iff `x` comes before `y` in the ordering, or is equal to `y`.
59
48
*/
60
49
override def lteq (x : T , y : T ): Boolean = compare(x, y) <= 0
61
50
62
- /** Returns <code>true</code> iff <code>y</code> comes before
63
- * <code>x</code> in the ordering.
51
+ /** @return true iff `x` comes after `y` in the ordering, or is equal to `y`.
64
52
*/
65
53
override def gteq (x : T , y : T ): Boolean = compare(x, y) >= 0
66
54
67
- /** Returns <code>true</code> iff <code>x</code> comes before
68
- * <code>y</code> in the ordering and is not the same as <code>y</code>.
55
+ /** @return true iff `x` comes before `y` in the ordering, and is not equal to `y`.
69
56
*/
70
57
override def lt (x : T , y : T ): Boolean = compare(x, y) < 0
71
58
72
- /** Returns <code>true</code> iff <code>y</code> comes before
73
- * <code>x</code> in the ordering and is not the same as <code>x</code>.
59
+ /** @return true iff `y` comes before `x` in the ordering, and is not equal to `x`.
74
60
*/
75
61
override def gt (x : T , y : T ): Boolean = compare(x, y) > 0
76
62
77
- /** Returns <code>true</code> iff <code>x</code> is equivalent to
78
- * <code>y</code> in the ordering.
63
+ /** @return true iff `x` is equivalent to `y` in the ordering.
79
64
*/
80
65
override def equiv (x : T , y : T ): Boolean = compare(x, y) == 0
81
66
@@ -85,7 +70,7 @@ trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializabl
85
70
/** Returns the argument which comes earlier in the ordering. */
86
71
def min (x : T , y : T ): T = if (lteq(x, y)) x else y
87
72
88
- override def reverse : Ordering [T ] = new Ordering [T ]{
73
+ override def reverse : Ordering [T ] = new Ordering [T ] {
89
74
override def reverse = outer
90
75
def compare (x : T , y : T ) = outer.compare(y, x)
91
76
}
@@ -107,26 +92,6 @@ trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializabl
107
92
implicit def mkOrderingOps (lhs : T ): Ops = new Ops (lhs)
108
93
}
109
94
110
- trait ExtraOrderingImplicits {
111
- /** Not in the standard scope due to the potential for divergence:
112
- * For instance implicitly[Ordering[Any]] diverges in its presence.
113
- */
114
- implicit def SeqDerived [CC [X ] <: collection.Seq [X ], T ](implicit ord : Ordering [T ]): Ordering [CC [T ]] =
115
- new Ordering [CC [T ]] {
116
- def compare (x : CC [T ], y : CC [T ]): Int = {
117
- val xe = x.iterator
118
- val ye = y.iterator
119
-
120
- while (xe.hasNext && ye.hasNext) {
121
- val res = ord.compare(xe.next, ye.next)
122
- if (res != 0 ) return res
123
- }
124
-
125
- Ordering .Boolean .compare(xe.hasNext, ye.hasNext)
126
- }
127
- }
128
- }
129
-
130
95
trait LowPriorityOrderingImplicits {
131
96
/** This would conflict with all the nice implicit Orderings
132
97
* available, but thanks to the magic of prioritized implicits
@@ -145,12 +110,39 @@ trait LowPriorityOrderingImplicits {
145
110
object Ordering extends LowPriorityOrderingImplicits {
146
111
def apply [T ](implicit ord : Ordering [T ]) = ord
147
112
113
+ trait ExtraImplicits {
114
+ /** Not in the standard scope due to the potential for divergence:
115
+ * For instance implicitly[Ordering[Any]] diverges in its presence.
116
+ */
117
+ implicit def seqDerivedOrdering [CC [X ] <: collection.Seq [X ], T ](implicit ord : Ordering [T ]): Ordering [CC [T ]] =
118
+ new Ordering [CC [T ]] {
119
+ def compare (x : CC [T ], y : CC [T ]): Int = {
120
+ val xe = x.iterator
121
+ val ye = y.iterator
122
+
123
+ while (xe.hasNext && ye.hasNext) {
124
+ val res = ord.compare(xe.next, ye.next)
125
+ if (res != 0 ) return res
126
+ }
127
+
128
+ Ordering .Boolean .compare(xe.hasNext, ye.hasNext)
129
+ }
130
+ }
131
+
132
+ /** This implicit creates a conversion from any value for which an implicit Ordering
133
+ * exists to the class which creates infix operations. With it imported, you can write
134
+ * methods as follows:
135
+ * {{{
136
+ * def lessThen[T: Ordering](x: T, y: T) = x < y
137
+ * }}}
138
+ */
139
+ implicit def infixOrderingOps [T ](x : T )(implicit ord : Ordering [T ]): Ordering [T ]# Ops = new ord.Ops (x)
140
+ }
141
+
148
142
/** An object for implicits which for one reason or another we
149
143
* aren't ready to put in the default scope.
150
144
*/
151
- object Implicits extends ExtraOrderingImplicits {
152
-
153
- }
145
+ object Implicits extends ExtraImplicits { }
154
146
155
147
def fromLessThan [T ](cmp : (T , T ) => Boolean ): Ordering [T ] = new Ordering [T ] {
156
148
def compare (x : T , y : T ) = if (cmp(x, y)) - 1 else if (cmp(y, x)) 1 else 0
0 commit comments