From 4ec7f11a799444c3758e94b3fdf9fa5c26330577 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 29 Nov 2010 22:59:28 +0000 Subject: Fleshed out Equiv[T] so that it can be used in ... Fleshed out Equiv[T] so that it can be used in a manner similar to Ordering[T]. No review. --- src/library/scala/math/Equiv.scala | 69 ++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 26 deletions(-) (limited to 'src/library') diff --git a/src/library/scala/math/Equiv.scala b/src/library/scala/math/Equiv.scala index a45b51af49..c09b4c577b 100644 --- a/src/library/scala/math/Equiv.scala +++ b/src/library/scala/math/Equiv.scala @@ -6,40 +6,57 @@ ** |/ ** \* */ - - package scala.math -/**

- * A trait for representing equivalence relations. It is important to - * distinguish between a type that can be compared for equality or - * equivalence and a representation of equivalence on some type. This - * trait is for representing the latter. - *

- *

- * An equivalence - * relation is a binary relation on a type. This relation is exposed as - * the equiv method of the Equiv trait. This - * relation must be: - *

- * +import java.util.Comparator + +/** A trait for representing equivalence relations. It is important to + * distinguish between a type that can be compared for equality or + * equivalence and a representation of equivalence on some type. This + * trait is for representing the latter. * - * @author Geoffrey Washburn + * An equivalence + * relation is a binary relation on a type. This relation is exposed as + * the `equiv` method of the `Equiv` trait. The relation must be: + * + * 1. reflexive: equiv(x, x) == true for any x of type T. + * 2. symmetric: equiv(x, y) == equiv(y, x) for any x and y of type T. + * 3. transitive: if equiv(x, y) == true and equiv(y, z) == true, then + * equiv(x, z) == true for any x, y, and z of type T. + * + * @author Geoffrey Washburn, Paul Phillips * @version 1.0, 2008-04-03 * @since 2.7 */ trait Equiv[T] { - /** Returns true iff x is equivalent to - * y. + /** Returns true iff x is equivalent to y. */ def equiv(x: T, y: T): Boolean } + +trait LowPriorityEquiv { + self: Equiv.type => + + implicit def universalEquiv[T] : Equiv[T] = universal[T] + + implicit def comparatorToEquiv[T](cmp: Comparator[T]): Equiv[T] = new Equiv[T] { + def equiv(x: T, y: T) = cmp.compare(x, y) == 0 + } +} + +object Equiv extends LowPriorityEquiv { + def reference[T <: AnyRef] : Equiv[T] = new Equiv[T] { + def equiv(x: T, y: T) = x eq y + } + def universal[T] : Equiv[T] = new Equiv[T] { + def equiv(x: T, y: T) = x == y + } + def fromFunction[T](cmp: (T, T) => Boolean): Equiv[T] = new Equiv[T] { + def equiv(x: T, y: T) = cmp(x, y) + } + def by[T, S: Equiv](f: T => S): Equiv[T] = + fromFunction((x, y) => implicitly[Equiv[S]].equiv(f(x), f(y))) + + def apply[T: Equiv] : Equiv[T] = implicitly[Equiv[T]] +} -- cgit v1.2.3