|
| 1 | +package scala |
| 2 | + |
| 3 | +import annotation.implicitNotFound |
| 4 | +import scala.collection.{Seq, Set} |
| 5 | + |
| 6 | +/** A marker trait indicating that values of type `L` can be compared to values of type `R`. */ |
| 7 | +@implicitNotFound("Values of types ${L} and ${R} cannot be compared with == or !=") |
| 8 | +sealed trait CanEqual[-L, -R] |
| 9 | + |
| 10 | +/** Companion object containing a few universally known `CanEqual` instances. |
| 11 | + * CanEqual instances involving primitive types or the Null type are handled directly in |
| 12 | + * the compiler (see Implicits.synthesizedCanEqual), so they are not included here. |
| 13 | + */ |
| 14 | +object CanEqual { |
| 15 | + /** A universal `CanEqual` instance. */ |
| 16 | + object derived extends CanEqual[Any, Any] |
| 17 | + |
| 18 | + /** A fall-back instance to compare values of any types. |
| 19 | + * Even though this method is not declared as given, the compiler will |
| 20 | + * synthesize implicit arguments as solutions to `CanEqual[T, U]` queries if |
| 21 | + * the rules of multiversal equality require it. |
| 22 | + */ |
| 23 | + def eqlAny[L, R]: CanEqual[L, R] = derived |
| 24 | + |
| 25 | + // Instances of `CanEqual` for common Java types |
| 26 | + given eqlNumber as CanEqual[Number, Number] = derived |
| 27 | + given eqlString as CanEqual[String, String] = derived |
| 28 | + |
| 29 | + // The next three definitions can go into the companion objects of classes |
| 30 | + // Seq and Set. For now they are here in order not to have to touch the |
| 31 | + // source code of these classes |
| 32 | + given eqlSeq[T, U](using eq: CanEqual[T, U]) as CanEqual[Seq[T], Seq[U]] = derived |
| 33 | + given eqlSet[T, U](using eq: CanEqual[T, U]) as CanEqual[Set[T], Set[U]] = derived |
| 34 | +} |
0 commit comments