Skip to content
This repository was archived by the owner on Feb 23, 2018. It is now read-only.

Commit f23af51

Browse files
author
extempore
committed
Leveraged having a place to put some useful implicits which we
sensibly are reluctant to introduce in the default scope. The test case pretty much sums it up. import Ordering.Implicits._ import Numeric.Implicits._ def f1[T: Numeric](x: T, y: T, z: T) = x + y + z def f2[T: Ordering](x: T, y: T, z: T) = if (x < y) (z > y) else (x < z) No review. git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@24468 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
1 parent 5ffa2a4 commit f23af51

File tree

4 files changed

+71
-64
lines changed

4 files changed

+71
-64
lines changed

src/library/scala/math/Fractional.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
** |/ **
77
\* */
88

9-
10-
119
package scala.math
1210

1311
/**

src/library/scala/math/Numeric.scala

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,24 @@
66
** |/ **
77
\* */
88

9-
10-
119
package scala.math
1210

1311
/**
1412
* @since 2.8
1513
*/
1614
object Numeric {
15+
trait ExtraImplicits {
16+
/** These implicits create conversions from a value for which an implicit Numeric
17+
* exists to the inner class which creates infix operations. Once imported, you
18+
* can write methods as follows:
19+
* {{{
20+
* def plus[T: Numeric](x: T, y: T) = x + y
21+
* }}}
22+
*/
23+
implicit def infixNumericOps[T](x: T)(implicit num: Numeric[T]): Numeric[T]#Ops = new num.Ops(x)
24+
}
25+
object Implicits extends ExtraImplicits { }
26+
1727
trait BigIntIsIntegral extends Integral[BigInt] {
1828
def plus(x: BigInt, y: BigInt): BigInt = x + y
1929
def minus(x: BigInt, y: BigInt): BigInt = x - y

src/library/scala/math/Ordering.scala

Lines changed: 52 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,25 @@
66
** |/ **
77
\* */
88

9-
10-
119
package scala.math
1210

1311
import java.util.Comparator
1412

1513
/** A trait for representing total orderings. It is important to
1614
* 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.
1921
*
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.
2422
* 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) &gt;= 0</code> and <code>math.signum(v) &gt;= 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+
}}}
3828
*
3929
* @author Geoffrey Washburn
4030
* @version 0.9.5, 2008-04-15
@@ -46,36 +36,31 @@ trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializabl
4636
/** An Ordering is defined at all x and y. */
4737
def tryCompare(x: T, y: T) = Some(compare(x, y))
4838

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.
5444
*/
5545
def compare(x: T, y: T): Int
5646

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`.
5948
*/
6049
override def lteq(x: T, y: T): Boolean = compare(x, y) <= 0
6150

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`.
6452
*/
6553
override def gteq(x: T, y: T): Boolean = compare(x, y) >= 0
6654

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`.
6956
*/
7057
override def lt(x: T, y: T): Boolean = compare(x, y) < 0
7158

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`.
7460
*/
7561
override def gt(x: T, y: T): Boolean = compare(x, y) > 0
7662

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.
7964
*/
8065
override def equiv(x: T, y: T): Boolean = compare(x, y) == 0
8166

@@ -85,7 +70,7 @@ trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializabl
8570
/** Returns the argument which comes earlier in the ordering. */
8671
def min(x: T, y: T): T = if (lteq(x, y)) x else y
8772

88-
override def reverse: Ordering[T] = new Ordering[T]{
73+
override def reverse: Ordering[T] = new Ordering[T] {
8974
override def reverse = outer
9075
def compare(x: T, y: T) = outer.compare(y, x)
9176
}
@@ -107,26 +92,6 @@ trait Ordering[T] extends Comparator[T] with PartialOrdering[T] with Serializabl
10792
implicit def mkOrderingOps(lhs: T): Ops = new Ops(lhs)
10893
}
10994

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-
13095
trait LowPriorityOrderingImplicits {
13196
/** This would conflict with all the nice implicit Orderings
13297
* available, but thanks to the magic of prioritized implicits
@@ -145,12 +110,39 @@ trait LowPriorityOrderingImplicits {
145110
object Ordering extends LowPriorityOrderingImplicits {
146111
def apply[T](implicit ord: Ordering[T]) = ord
147112

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+
148142
/** An object for implicits which for one reason or another we
149143
* aren't ready to put in the default scope.
150144
*/
151-
object Implicits extends ExtraOrderingImplicits {
152-
153-
}
145+
object Implicits extends ExtraImplicits { }
154146

155147
def fromLessThan[T](cmp: (T, T) => Boolean): Ordering[T] = new Ordering[T] {
156148
def compare(x: T, y: T) = if (cmp(x, y)) -1 else if (cmp(y, x)) 1 else 0
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
object Test {
2+
import Ordering.Implicits._
3+
import Numeric.Implicits._
4+
5+
def f1[T: Numeric](x: T, y: T, z: T) = x + y + z
6+
def f2[T: Ordering](x: T, y: T, z: T) = if (x < y) (z > y) else (x < z)
7+
}

0 commit comments

Comments
 (0)