From 0df28504f8676ba8736faa54e2540e4bc36e43d2 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Thu, 28 May 2009 16:27:13 +0000 Subject: Further development of the Numeric and Ordering... Further development of the Numeric and Ordering traits. Replaced Predef implicits from everything => Ordered with a single implicit from Ordering => Ordered. --- src/cldc-library/scala/List.scala | 19 ----- src/cldc-library/scala/Predef.scala | 103 +--------------------------- src/compiler/scala/tools/nsc/Settings.scala | 2 +- src/dotnet-library/scala/Predef.scala | 103 +--------------------------- src/library/scala/BigDecimal.scala | 7 -- src/library/scala/BigInt.scala | 7 -- src/library/scala/Numeric.scala | 34 ++++----- src/library/scala/Ordering.scala | 79 ++++++++++++++------- src/library/scala/Predef.scala | 101 ++------------------------- src/library/scala/Range.scala | 18 +++-- test/files/neg/bug900.check | 4 +- 11 files changed, 90 insertions(+), 387 deletions(-) diff --git a/src/cldc-library/scala/List.scala b/src/cldc-library/scala/List.scala index 71bf2f1ca2..35f8d45760 100644 --- a/src/cldc-library/scala/List.scala +++ b/src/cldc-library/scala/List.scala @@ -357,25 +357,6 @@ object List { def transpose[A](xss: List[List[A]]): List[List[A]] = if (xss.head.isEmpty) List() else (xss map (xs => xs.head)) :: transpose(xss map (xs => xs.tail)) - - /** Lists with ordered elements are ordered - implicit def list2ordered[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] { - def compare [b >: List[a] <% Ordered[b]](y: b): Int = y match { - case y1: List[a] => compareLists(x, y1); - case _ => -(y compare x) - } - private def compareLists(xs: List[a], ys: List[a]): Int = { - if (xs.isEmpty && ys.isEmpty) 0 - else if (xs.isEmpty) -1 - else if (ys.isEmpty) 1 - else { - val s = xs.head compare ys.head; - if (s != 0) s - else compareLists(xs.tail, ys.tail) - } - } - } - */ } /** A class representing an ordered collection of elements of type diff --git a/src/cldc-library/scala/Predef.scala b/src/cldc-library/scala/Predef.scala index bbb4478412..94adbe0bde 100644 --- a/src/cldc-library/scala/Predef.scala +++ b/src/cldc-library/scala/Predef.scala @@ -155,106 +155,9 @@ object Predef { implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc) - implicit def unit2ordered(x: Unit): Ordered[Unit] = new Ordered[Unit] with Proxy { - def self: Any = x - def compare(y: Unit): Int = 0 - } - - implicit def iterable2ordered[A <% Ordered[A]](xs: Iterable[A]): Ordered[Iterable[A]] = - new Ordered[Iterable[A]] with Proxy { - val self = xs - def compare(that: Iterable[A]): Int = { - var res = 0 - val these = xs.iterator - val those = that.iterator - while (res == 0 && these.hasNext) - res = if (those.hasNext) these.next compare those.next else 1 - if (res == 0) { - if (those.hasNext) -1 else 0 - } else - res - } - } - - implicit def tuple22ordered[A1 <% Ordered[A1], A2 <% Ordered[A2]](x: Tuple2[A1, A2]): Ordered[Tuple2[A1, A2]] = - new Ordered[Tuple2[A1, A2]] with Proxy { - val self = x - def compare(y: Tuple2[A1, A2]): Int = { - val res = x._1 compare y._1 - if (res == 0) x._2 compare y._2 - else res - } - } - - implicit def tuple32ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3]](x: Tuple3[A1, A2, A3]): Ordered[Tuple3[A1, A2, A3]] = - new Ordered[Tuple3[A1, A2, A3]] with Proxy { - val self = x - def compare(y: Tuple3[A1, A2, A3]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple2(x._2, x._3) compare Tuple2(y._2, y._3) - else res - } - } - - implicit def tuple42ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4]](x: Tuple4[A1, A2, A3, A4]): Ordered[Tuple4[A1, A2, A3, A4]] = - new Ordered[Tuple4[A1, A2, A3, A4]] with Proxy { - val self = x - def compare(y: Tuple4[A1, A2, A3, A4]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple3(x._2, x._3, x._4) compare Tuple3(y._2, y._3, y._4) - else res - } - } - - implicit def tuple52ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5]](x: Tuple5[A1, A2, A3, A4, A5]): Ordered[Tuple5[A1, A2, A3, A4, A5]] = - new Ordered[Tuple5[A1, A2, A3, A4, A5]] with Proxy { - val self = x - def compare(y: Tuple5[A1, A2, A3, A4, A5]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple4(x._2, x._3, x._4, x._5) compare Tuple4(y._2, y._3, y._4, y._5) - else res - } - } - - implicit def tuple62ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6]](x: Tuple6[A1, A2, A3, A4, A5, A6]): Ordered[Tuple6[A1, A2, A3, A4, A5, A6]] = - new Ordered[Tuple6[A1, A2, A3, A4, A5, A6]] with Proxy { - val self = x - def compare(y: Tuple6[A1, A2, A3, A4, A5, A6]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple5(x._2, x._3, x._4, x._5, x._6) compare Tuple5(y._2, y._3, y._4, y._5, y._6) - else res - } - } - - implicit def tuple72ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6], A7 <% Ordered[A7]](x: Tuple7[A1, A2, A3, A4, A5, A6, A7]): Ordered[Tuple7[A1, A2, A3, A4, A5, A6, A7]] = - new Ordered[Tuple7[A1, A2, A3, A4, A5, A6, A7]] with Proxy { - val self = x - def compare(y: Tuple7[A1, A2, A3, A4, A5, A6, A7]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple6(x._2, x._3, x._4, x._5, x._6, x._7) compare Tuple6(y._2, y._3, y._4, y._5, y._6, y._7) - else res - } - } - - implicit def tuple82ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6], A7 <% Ordered[A7], A8 <% Ordered[A8]](x: Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]): Ordered[Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] = - new Ordered[Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] with Proxy { - val self = x - def compare(y: Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple7(x._2, x._3, x._4, x._5, x._6, x._7, x._8) compare Tuple7(y._2, y._3, y._4, y._5, y._6, y._7, y._8) - else res - } - } - - implicit def tuple92ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6], A7 <% Ordered[A7], A8 <% Ordered[A8], A9 <% Ordered[A9]](x: Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]): Ordered[Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] = - new Ordered[Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] with Proxy { - val self = x - def compare(y: Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple8(x._2, x._3, x._4, x._5, x._6, x._7, x._8, x._9) compare Tuple8(y._2, y._3, y._4, y._5, y._6, y._7, y._8, y._9) - else res - } - } + /** Lens from Ordering[T] to Ordered[T] */ + implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] = + new Ordered[T] { def compare(that: T): Int = ord.compare(x, that) } implicit def byte2short(x: Byte): Short = x.toShort implicit def byte2int(x: Byte): Int = x.toInt diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 5d96a54f64..dd504e3781 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -397,7 +397,7 @@ object Settings // Ordered (so we can use TreeSet) def compare(that: Setting): Int = name compare that.name - def compareLists[T <% Ordered[T]](xs: List[T], ys: List[T]) = xs.sort(_ < _) == ys.sort(_ < _) + def compareLists[T <% Ordered[T]](xs: List[T], ys: List[T]): Boolean = xs.sort(_ < _) == ys.sort(_ < _) // Equality def eqValues: List[Any] = List(name, value) diff --git a/src/dotnet-library/scala/Predef.scala b/src/dotnet-library/scala/Predef.scala index bfcbc461b3..3212ae50b5 100644 --- a/src/dotnet-library/scala/Predef.scala +++ b/src/dotnet-library/scala/Predef.scala @@ -201,106 +201,9 @@ object Predef { implicit def classWrapper(clazz: Class[_]): runtime.RichClass = new runtime.RichClass(clazz) - implicit def unit2ordered(x: Unit): Ordered[Unit] = new Ordered[Unit] with Proxy { - def self: Any = x - def compare(y: Unit): Int = 0 - } - - implicit def iterable2ordered[A <% Ordered[A]](xs: Iterable[A]): Ordered[Iterable[A]] = - new Ordered[Iterable[A]] with Proxy { - val self = xs - def compare(that: Iterable[A]): Int = { - var res = 0 - val these = xs.iterator - val those = that.iterator - while (res == 0 && these.hasNext) - res = if (those.hasNext) these.next compare those.next else 1 - if (res == 0) { - if (those.hasNext) -1 else 0 - } else - res - } - } - - implicit def tuple22ordered[A1 <% Ordered[A1], A2 <% Ordered[A2]](x: Tuple2[A1, A2]): Ordered[Tuple2[A1, A2]] = - new Ordered[Tuple2[A1, A2]] with Proxy { - val self = x - def compare(y: Tuple2[A1, A2]): Int = { - val res = x._1 compare y._1 - if (res == 0) x._2 compare y._2 - else res - } - } - - implicit def tuple32ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3]](x: Tuple3[A1, A2, A3]): Ordered[Tuple3[A1, A2, A3]] = - new Ordered[Tuple3[A1, A2, A3]] with Proxy { - val self = x - def compare(y: Tuple3[A1, A2, A3]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple2(x._2, x._3) compare Tuple2(y._2, y._3) - else res - } - } - - implicit def tuple42ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4]](x: Tuple4[A1, A2, A3, A4]): Ordered[Tuple4[A1, A2, A3, A4]] = - new Ordered[Tuple4[A1, A2, A3, A4]] with Proxy { - val self = x - def compare(y: Tuple4[A1, A2, A3, A4]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple3(x._2, x._3, x._4) compare Tuple3(y._2, y._3, y._4) - else res - } - } - - implicit def tuple52ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5]](x: Tuple5[A1, A2, A3, A4, A5]): Ordered[Tuple5[A1, A2, A3, A4, A5]] = - new Ordered[Tuple5[A1, A2, A3, A4, A5]] with Proxy { - val self = x - def compare(y: Tuple5[A1, A2, A3, A4, A5]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple4(x._2, x._3, x._4, x._5) compare Tuple4(y._2, y._3, y._4, y._5) - else res - } - } - - implicit def tuple62ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6]](x: Tuple6[A1, A2, A3, A4, A5, A6]): Ordered[Tuple6[A1, A2, A3, A4, A5, A6]] = - new Ordered[Tuple6[A1, A2, A3, A4, A5, A6]] with Proxy { - val self = x - def compare(y: Tuple6[A1, A2, A3, A4, A5, A6]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple5(x._2, x._3, x._4, x._5, x._6) compare Tuple5(y._2, y._3, y._4, y._5, y._6) - else res - } - } - - implicit def tuple72ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6], A7 <% Ordered[A7]](x: Tuple7[A1, A2, A3, A4, A5, A6, A7]): Ordered[Tuple7[A1, A2, A3, A4, A5, A6, A7]] = - new Ordered[Tuple7[A1, A2, A3, A4, A5, A6, A7]] with Proxy { - val self = x - def compare(y: Tuple7[A1, A2, A3, A4, A5, A6, A7]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple6(x._2, x._3, x._4, x._5, x._6, x._7) compare Tuple6(y._2, y._3, y._4, y._5, y._6, y._7) - else res - } - } - - implicit def tuple82ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6], A7 <% Ordered[A7], A8 <% Ordered[A8]](x: Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]): Ordered[Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] = - new Ordered[Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] with Proxy { - val self = x - def compare(y: Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple7(x._2, x._3, x._4, x._5, x._6, x._7, x._8) compare Tuple7(y._2, y._3, y._4, y._5, y._6, y._7, y._8) - else res - } - } - - implicit def tuple92ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6], A7 <% Ordered[A7], A8 <% Ordered[A8], A9 <% Ordered[A9]](x: Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]): Ordered[Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] = - new Ordered[Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] with Proxy { - val self = x - def compare(y: Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple8(x._2, x._3, x._4, x._5, x._6, x._7, x._8, x._9) compare Tuple8(y._2, y._3, y._4, y._5, y._6, y._7, y._8, y._9) - else res - } - } + /** Lens from Ordering[T] to Ordered[T] */ + implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] = + new Ordered[T] { def compare(that: T): Int = ord.compare(x, that) } implicit def byte2short(x: Byte): Short = x.toShort implicit def byte2int(x: Byte): Int = x.toInt diff --git a/src/library/scala/BigDecimal.scala b/src/library/scala/BigDecimal.scala index c735bb54b9..0203a6022a 100644 --- a/src/library/scala/BigDecimal.scala +++ b/src/library/scala/BigDecimal.scala @@ -106,13 +106,6 @@ object BigDecimal { * @since 2.8 */ implicit def bigInt2bigDecimal(x: BigInt): BigDecimal = apply(x) - - /** Implicit conversion from BigDecimal to Ordered. */ - implicit def bigDecimal2ordered(x: BigDecimal): Ordered[BigDecimal] = - new Ordered[BigDecimal] with Proxy { - def self: Any = x - def compare(y: BigDecimal): Int = x.bigDecimal.compareTo(y.bigDecimal) - } } /** diff --git a/src/library/scala/BigInt.scala b/src/library/scala/BigInt.scala index c03238680e..ac8b4c40a7 100644 --- a/src/library/scala/BigInt.scala +++ b/src/library/scala/BigInt.scala @@ -101,13 +101,6 @@ object BigInt { /** Implicit copnversion from long to BigInt */ implicit def long2bigInt(l: Long): BigInt = apply(l) - - /** Implicit conversion from BigInt to Ordered. - */ - implicit def bigInt2ordered(x: BigInt): Ordered[BigInt] = new Ordered[BigInt] with Proxy { - def self: Any = x; - def compare (y: BigInt): Int = x.bigInteger.compareTo(y.bigInteger) - } } /** diff --git a/src/library/scala/Numeric.scala b/src/library/scala/Numeric.scala index ba48db9c1d..cd563609c9 100755 --- a/src/library/scala/Numeric.scala +++ b/src/library/scala/Numeric.scala @@ -8,15 +8,13 @@ object Numeric { def quot(x: BigInt, y: BigInt): BigInt = x / y def rem(x: BigInt, y: BigInt): BigInt = x % y def negate(x: BigInt): BigInt = -x - def abs(x: BigInt): BigInt = if (x < 0) -x else x - def signum(x: BigInt): BigInt = if (x < 0) -1 else if (x > 0) 1 else 0 def fromInt(x: Int): BigInt = BigInt(x) def toInt(x: BigInt): Int = x.intValue def toLong(x: BigInt): Long = x.longValue def toFloat(x: BigInt): Float = x.longValue.toFloat def toDouble(x: BigInt): Double = x.longValue.toDouble } - implicit object BigIntIsIntegral extends BigIntIsIntegral + implicit object BigIntIsIntegral extends BigIntIsIntegral with Ordering.BigIntOrdering trait IntIsIntegral extends Integral[Int] { def plus(x: Int, y: Int): Int = x + y @@ -25,15 +23,13 @@ object Numeric { def quot(x: Int, y: Int): Int = x / y def rem(x: Int, y: Int): Int = x % y def negate(x: Int): Int = -x - def abs(x: Int): Int = if (x < 0) -x else x - def signum(x: Int): Int = if (x < 0) -1 else if (x > 0) 1 else 0 def fromInt(x: Int): Int = x def toInt(x: Int): Int = x def toLong(x: Int): Long = x def toFloat(x: Int): Float = x def toDouble(x: Int): Double = x } - implicit object IntIsIntegral extends IntIsIntegral + implicit object IntIsIntegral extends IntIsIntegral with Ordering.IntOrdering trait LongIsIntegral extends Integral[Long] { def plus(x: Long, y: Long): Long = x + y @@ -42,15 +38,13 @@ object Numeric { def quot(x: Long, y: Long): Long = x / y def rem(x: Long, y: Long): Long = x % y def negate(x: Long): Long = -x - def abs(x: Long): Long = if (x < 0) -x else x - def signum(x: Long): Long = if (x < 0) -1 else if (x > 0) 1 else 0 def fromInt(x: Int): Long = x def toInt(x: Long): Int = x.toInt def toLong(x: Long): Long = x def toFloat(x: Long): Float = x def toDouble(x: Long): Double = x } - implicit object LongIsIntegral extends LongIsIntegral + implicit object LongIsIntegral extends LongIsIntegral with Ordering.LongOrdering trait FloatIsFractional extends Fractional[Float] { def plus(x: Float, y: Float): Float = x + y @@ -58,15 +52,13 @@ object Numeric { def times(x: Float, y: Float): Float = x * y def div(x: Float, y: Float): Float = x / y def negate(x: Float): Float = -x - def abs(x: Float): Float = if (x < 0) -x else x - def signum(x: Float): Float = if (x < 0) -1 else if (x > 0) 1 else 0 def fromInt(x: Int): Float = x def toInt(x: Float): Int = x.toInt def toLong(x: Float): Long = x.toLong def toFloat(x: Float): Float = x def toDouble(x: Float): Double = x } - implicit object FloatIsFractional extends FloatIsFractional + implicit object FloatIsFractional extends FloatIsFractional with Ordering.FloatOrdering trait DoubleIsFractional extends Fractional[Double] { def plus(x: Double, y: Double): Double = x + y @@ -74,40 +66,42 @@ object Numeric { def times(x: Double, y: Double): Double = x * y def div(x: Double, y: Double): Double = x / y def negate(x: Double): Double = -x - def abs(x: Double): Double = if (x < 0) -x else x - def signum(x: Double): Double = if (x < 0) -1 else if (x > 0) 1 else 0 def fromInt(x: Int): Double = x def toInt(x: Double): Int = x.toInt def toLong(x: Double): Long = x.toLong def toFloat(x: Double): Float = x.toFloat def toDouble(x: Double): Double = x } - implicit object DoubleIsFractional extends DoubleIsFractional - + implicit object DoubleIsFractional extends DoubleIsFractional with Ordering.DoubleOrdering } -trait Numeric[T] { +trait Numeric[T] extends Ordering[T] { def plus(x: T, y: T): T def minus(x: T, y: T): T def times(x: T, y: T): T def negate(x: T): T - def abs(x: T): T - def signum(x: T): T def fromInt(x: Int): T def toInt(x: T): Int def toLong(x: T): Long def toFloat(x: T): Float def toDouble(x: T): Double + def zero = fromInt(0) def one = fromInt(1) + def abs(x: T): T = if (lt(x, zero)) negate(x) else x + def signum(x: T): Int = + if (lt(x, zero)) -1 + else if (gt(x, zero)) 1 + else 0 + class Ops(lhs: T) { def +(rhs: T) = plus(lhs, rhs) def -(rhs: T) = minus(lhs, rhs) def *(rhs: T) = times(lhs, rhs) def unary_-() = negate(lhs) def abs(): T = Numeric.this.abs(lhs) - def signum(): T = Numeric.this.signum(lhs) + def signum(): Int = Numeric.this.signum(lhs) def toInt(): Int = Numeric.this.toInt(lhs) def toLong(): Long = Numeric.this.toLong(lhs) def toFloat(): Float = Numeric.this.toFloat(lhs) diff --git a/src/library/scala/Ordering.scala b/src/library/scala/Ordering.scala index 467a46f724..1a30e24124 100644 --- a/src/library/scala/Ordering.scala +++ b/src/library/scala/Ordering.scala @@ -72,13 +72,20 @@ trait Ordering[T] extends PartialOrdering[T] { */ override def equiv(x: T, y: T): Boolean = compare(x, y) == 0 + /** Returns the argument which comes later in the ordering. */ + def max(x: T, y: T): T = if (gteq(x, y)) x else y + + /** Returns the argument which comes earlier in the ordering. */ + def min(x: T, y: T): T = if (lteq(x, y)) x else y + class Ops(lhs: T) { def <(rhs: T) = lt(lhs, rhs) def <=(rhs: T) = lteq(lhs, rhs) def >(rhs: T) = gt(lhs, rhs) def >=(rhs: T) = gteq(lhs, rhs) - def ===(rhs: T) = equiv(lhs, rhs) - def !==(rhs: T) = !equiv(lhs, rhs) + def equiv(rhs: T) = Ordering.this.equiv(lhs, rhs) + def max(rhs: T): T = Ordering.this.max(lhs, rhs) + def min(rhs: T): T = Ordering.this.min(lhs, rhs) } implicit def mkOrderingOps(lhs: T): Ops = new Ops(lhs) } @@ -87,65 +94,87 @@ object Ordering { def apply[T](implicit ord : Ordering[T]) = ord - implicit val Unit : Ordering[Unit] = new Ordering[Unit] { + trait UnitOrdering extends Ordering[Unit] { def compare(x : Unit, y : Unit) = 0; } - - implicit val Boolean : Ordering[Boolean] = new Ordering[Boolean] { + // XXX For the time being this is non-implicit so there remains + // only one default implicit conversion Unit => AnyRef (the other + // being any2stringadd in Predef.) See + // test/files/neg/structural.scala + // for an example of code which is influenced by the next line. + // implicit object Unit extends UnitOrdering + object Unit extends UnitOrdering + + trait BooleanOrdering extends Ordering[Boolean] { def compare(x : Boolean, y : Boolean) = (x, y) match { case (false, true) => -1; case (true, false) => 1; case _ => 0; } } + implicit object Boolean extends BooleanOrdering - implicit val Byte : Ordering[Byte] = new Ordering[Byte] { + trait ByteOrdering extends Ordering[Byte] { def compare(x : Byte, y : Byte) = x.toInt - y.toInt; } + implicit object Byte extends ByteOrdering - implicit val Char : Ordering[Char] = new Ordering[Char] { + trait CharOrdering extends Ordering[Char] { def compare(x : Char, y : Char) = x.toInt - y.toInt; } + implicit object Char extends CharOrdering - implicit val Short : Ordering[Short] = new Ordering[Short] { + trait ShortOrdering extends Ordering[Short] { def compare(x : Short, y : Short) = x.toInt - y.toInt; } + implicit object Short extends ShortOrdering - implicit val Int : Ordering[Int] = new Ordering[Int] { + trait IntOrdering extends Ordering[Int] { def compare(x : Int, y : Int) = if(x < y) -1; else if (x == y) 0; else 1 } + implicit object Int extends IntOrdering - implicit val Long : Ordering[Long] = new Ordering[Long] { + trait LongOrdering extends Ordering[Long] { def compare(x : Long, y : Long) = if(x < y) -1; else if (x == y) 0; else 1 } + implicit object Long extends LongOrdering - implicit val Float : Ordering[Float] = new Ordering[Float] { + trait FloatOrdering extends Ordering[Float] { def compare(x : Float, y : Float) = if(x < y) -1; else if (x == y) 0; else 1 } + implicit object Float extends FloatOrdering - implicit val Double : Ordering[Double] = new Ordering[Double] { + trait DoubleOrdering extends Ordering[Double] { def compare(x : Double, y : Double) = if(x < y) -1; else if (x == y) 0; else 1 } + implicit object Double extends DoubleOrdering - implicit val BigInt : Ordering[BigInt] = new Ordering[BigInt] { + trait BigIntOrdering extends Ordering[BigInt] { def compare(x : BigInt, y : BigInt) = x.compare(y); } + implicit object BigInt extends BigIntOrdering + + trait BigDecimalOrdering extends Ordering[BigDecimal] { + def compare(x : BigDecimal, y : BigDecimal) = x.compare(y); + } + implicit object BigDecimal extends BigDecimalOrdering - implicit val String : Ordering[String] = new Ordering[String] { + trait StringOrdering extends Ordering[String] { def compare(x : String, y : String) = x.compareTo(y); } + implicit object String extends StringOrdering implicit def Option[T](implicit ord : Ordering[T]) : Ordering[Option[T]] = new Ordering[Option[T]] { @@ -158,19 +187,19 @@ object Ordering } implicit def Iterable[T](implicit ord : Ordering[T]) : Ordering[Iterable[T]] = - new Ordering[Iterable[T]] { - def compare(x : Iterable[T], y : Iterable[T]) : Int = { - val xe = x.iterator; - val ye = y.iterator; - - while (xe.hasNext && ye.hasNext){ - val res = ord.compare(xe.next, ye.next); - if (res != 0) return res; - } + new Ordering[Iterable[T]] { + def compare(x : Iterable[T], y : Iterable[T]) : Int = { + val xe = x.iterator; + val ye = y.iterator; + + while (xe.hasNext && ye.hasNext){ + val res = ord.compare(xe.next, ye.next); + if (res != 0) return res; + } - Boolean.compare(xe.hasNext, ye.hasNext); + Boolean.compare(xe.hasNext, ye.hasNext); + } } - } implicit def Tuple2[T1, T2](implicit ord1 : Ordering[T1], ord2 : Ordering[T2]) : Ordering[(T1, T2)] = new Ordering[(T1, T2)]{ diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 2c11c9a106..c2ade6dd0f 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -199,107 +199,16 @@ object Predef { implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc) + /** Lens from Ordering[T] to Ordered[T] */ + implicit def orderingToOrdered[T](x: T)(implicit ord: Ordering[T]): Ordered[T] = + new Ordered[T] { def compare(that: T): Int = ord.compare(x, that) } + + /** Temporarily leaving this conversion to Ordered - see Ordering.scala for reasoning */ implicit def unit2ordered(x: Unit): Ordered[Unit] = new Ordered[Unit] with Proxy { def self: Any = x def compare(y: Unit): Int = 0 } - implicit def iterable2ordered[A <% Ordered[A]](xs: Iterable[A]): Ordered[Iterable[A]] = - new Ordered[Iterable[A]] with Proxy { - val self = xs - def compare(that: Iterable[A]): Int = { - var res = 0 - val these = xs.iterator - val those = that.iterator - while (res == 0 && these.hasNext) - res = if (those.hasNext) these.next compare those.next else 1 - if (res == 0) { - if (those.hasNext) -1 else 0 - } else - res - } - } - - implicit def tuple22ordered[A1 <% Ordered[A1], A2 <% Ordered[A2]](x: Tuple2[A1, A2]): Ordered[Tuple2[A1, A2]] = - new Ordered[Tuple2[A1, A2]] with Proxy { - val self = x - def compare(y: Tuple2[A1, A2]): Int = { - val res = x._1 compare y._1 - if (res == 0) x._2 compare y._2 - else res - } - } - - implicit def tuple32ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3]](x: Tuple3[A1, A2, A3]): Ordered[Tuple3[A1, A2, A3]] = - new Ordered[Tuple3[A1, A2, A3]] with Proxy { - val self = x - def compare(y: Tuple3[A1, A2, A3]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple2(x._2, x._3) compare Tuple2(y._2, y._3) - else res - } - } - - implicit def tuple42ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4]](x: Tuple4[A1, A2, A3, A4]): Ordered[Tuple4[A1, A2, A3, A4]] = - new Ordered[Tuple4[A1, A2, A3, A4]] with Proxy { - val self = x - def compare(y: Tuple4[A1, A2, A3, A4]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple3(x._2, x._3, x._4) compare Tuple3(y._2, y._3, y._4) - else res - } - } - - implicit def tuple52ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5]](x: Tuple5[A1, A2, A3, A4, A5]): Ordered[Tuple5[A1, A2, A3, A4, A5]] = - new Ordered[Tuple5[A1, A2, A3, A4, A5]] with Proxy { - val self = x - def compare(y: Tuple5[A1, A2, A3, A4, A5]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple4(x._2, x._3, x._4, x._5) compare Tuple4(y._2, y._3, y._4, y._5) - else res - } - } - - implicit def tuple62ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6]](x: Tuple6[A1, A2, A3, A4, A5, A6]): Ordered[Tuple6[A1, A2, A3, A4, A5, A6]] = - new Ordered[Tuple6[A1, A2, A3, A4, A5, A6]] with Proxy { - val self = x - def compare(y: Tuple6[A1, A2, A3, A4, A5, A6]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple5(x._2, x._3, x._4, x._5, x._6) compare Tuple5(y._2, y._3, y._4, y._5, y._6) - else res - } - } - - implicit def tuple72ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6], A7 <% Ordered[A7]](x: Tuple7[A1, A2, A3, A4, A5, A6, A7]): Ordered[Tuple7[A1, A2, A3, A4, A5, A6, A7]] = - new Ordered[Tuple7[A1, A2, A3, A4, A5, A6, A7]] with Proxy { - val self = x - def compare(y: Tuple7[A1, A2, A3, A4, A5, A6, A7]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple6(x._2, x._3, x._4, x._5, x._6, x._7) compare Tuple6(y._2, y._3, y._4, y._5, y._6, y._7) - else res - } - } - - implicit def tuple82ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6], A7 <% Ordered[A7], A8 <% Ordered[A8]](x: Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]): Ordered[Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] = - new Ordered[Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]] with Proxy { - val self = x - def compare(y: Tuple8[A1, A2, A3, A4, A5, A6, A7, A8]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple7(x._2, x._3, x._4, x._5, x._6, x._7, x._8) compare Tuple7(y._2, y._3, y._4, y._5, y._6, y._7, y._8) - else res - } - } - - implicit def tuple92ordered[A1 <% Ordered[A1], A2 <% Ordered[A2], A3 <% Ordered[A3], A4 <% Ordered[A4], A5 <% Ordered[A5], A6 <% Ordered[A6], A7 <% Ordered[A7], A8 <% Ordered[A8], A9 <% Ordered[A9]](x: Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]): Ordered[Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] = - new Ordered[Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]] with Proxy { - val self = x - def compare(y: Tuple9[A1, A2, A3, A4, A5, A6, A7, A8, A9]): Int = { - val res = x._1 compare y._1 - if (res == 0) Tuple8(x._2, x._3, x._4, x._5, x._6, x._7, x._8, x._9) compare Tuple8(y._2, y._3, y._4, y._5, y._6, y._7, y._8, y._9) - else res - } - } - implicit def byte2short(x: Byte): Short = x.toShort implicit def byte2int(x: Byte): Int = x.toInt implicit def byte2long(x: Byte): Long = x.toLong diff --git a/src/library/scala/Range.scala b/src/library/scala/Range.scala index b2cb8c07c4..3be4dfb4ed 100644 --- a/src/library/scala/Range.scala +++ b/src/library/scala/Range.scala @@ -16,8 +16,8 @@ import collection.generic.VectorView /**

* GenericRange is a generified version of the * Range class which works with arbitrary types. - * It must be supplied with Integral and Ordering implementations - * of the range type. + * It must be supplied with an Integral implementation of the + * range type. * * Factories for likely types include Range.BigInt and Range.Long. * Range.Int exists for completeness, but the Int-based scala.Range @@ -34,10 +34,9 @@ import collection.generic.VectorView */ abstract class GenericRange[T] (val start: T, val end: T, val step: T) - (implicit num: Integral[T], ord: Ordering[T]) + (implicit num: Integral[T]) extends VectorView[T, Vector[T]] with RangeToString[T] { import num._ - import ord._ // this lets us pretend all ranges are exclusive val isInclusive: Boolean @@ -46,7 +45,7 @@ extends VectorView[T, Vector[T]] with RangeToString[T] { // todo? - we could lift the length restriction by implementing a range as a sequence of // subranges and limiting the subranges to MAX_INT. There's no other way around it because // the generics we inherit assume integer-based indexing (as well they should.) - require(step !== zero) + require(!(step equiv zero)) require(genericLength <= fromInt(Math.MAX_INT), "Implementation restricts ranges to Math.MAX_INT elements.") protected def underlying = Vector.empty[T] @@ -117,25 +116,24 @@ private[scala] trait RangeToString[T] extends VectorView[T, Vector[T]] { object GenericRange { import Numeric._ - import Ordering._ - class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T], ord: Ordering[T]) + class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) extends GenericRange(start, end, step) { val isInclusive = true def exclusive: Exclusive[T] = new Exclusive(start, end, step) } - class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T], ord: Ordering[T]) + class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) extends GenericRange(start, end, step) { val isInclusive = false def inclusive: Inclusive[T] = new Inclusive(start, end, step) } - def apply[T](start: T, end: T, step: T)(implicit num: Integral[T], ord: Ordering[T]) = + def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]) = new Exclusive(start, end, step) - def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T], ord: Ordering[T]) = + def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) = new Inclusive(start, end, step) } diff --git a/test/files/neg/bug900.check b/test/files/neg/bug900.check index 3ba577bbcd..778bce7c9f 100644 --- a/test/files/neg/bug900.check +++ b/test/files/neg/bug900.check @@ -2,8 +2,8 @@ bug900.scala:4: error: type mismatch; found : Foo.this.x.type (with underlying type Foo.this.bar) required: AnyRef Note that implicit conversions are not applicable because they are ambiguous: - both method any2stringadd in object Predef of type (Any)scala.runtime.StringAdd - and method any2ArrowAssoc in object Predef of type [A](A)ArrowAssoc[A] + both method orderingToOrdered in object Predef of type [T](T)(implicit Ordering[T])Ordered[T] + and method any2stringadd in object Predef of type (Any)scala.runtime.StringAdd are possible conversion functions from Foo.this.x.type to AnyRef def break(): x.type ^ -- cgit v1.2.3