Skip to content

Commit f320ac8

Browse files
committed
Straw man for multiversal equality.
This test shows how we can make equality non-universal in Scala. It also exhibited the two bugs fixed in the previous two commits. Also related: SI-9763.
1 parent 3c38a6b commit f320ac8

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

tests/neg/EqualityStrawman1.scala

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package strawman.equality
2+
3+
object EqualityStrawman1 {
4+
5+
trait Eq[-T]
6+
trait Impossible
7+
8+
object Eq extends Eq[Any]
9+
10+
trait Base {
11+
def === (other: Any): Boolean = this.equals(other)
12+
def === (other: CondEquals)(implicit ce: Impossible): Boolean = ???
13+
}
14+
15+
trait CondEquals extends Base {
16+
def === [T >: this.type <: CondEquals](other: T)(implicit ce: Eq[T]): Boolean = this.equals(other)
17+
def === (other: Any)(implicit ce: Impossible): Boolean = ???
18+
}
19+
20+
trait Equals[-T] extends CondEquals
21+
22+
case class Str(str: String) extends CondEquals
23+
24+
case class Num(x: Int) extends Equals[Num]
25+
26+
case class Other(x: Int) extends Base
27+
28+
trait Option[+T] extends CondEquals
29+
case class Some[+T](x: T) extends Option[T]
30+
case object None extends Option[Nothing]
31+
32+
implicit def eqStr: Eq[Str] = Eq
33+
//implicit def eqNum: Eq[Num] = Eq
34+
implicit def eqOption[T: Eq]: Eq[Option[T]] = Eq
35+
36+
implicit def eqEq[T <: Equals[T]]: Eq[T] = Eq
37+
38+
def main(args: Array[String]): Unit = {
39+
val x = Str("abc")
40+
x === x
41+
42+
val n = Num(2)
43+
val m = Num(3)
44+
n === m
45+
46+
Other(1) === Other(2)
47+
48+
Some(x) === None
49+
Some(x) === Some(Str(""))
50+
val z: Option[Str] = Some(Str("abc"))
51+
z === Some(x)
52+
z === None
53+
Some(x) === z
54+
None === z
55+
56+
57+
def ddistinct[T <: Base: Eq](xs: List[T]): List[T] = xs match {
58+
case Nil => Nil
59+
case x :: xs => x :: xs.filterNot(x === _)
60+
}
61+
62+
ddistinct(List(z, z, z))
63+
64+
x === n // error
65+
n === x // error
66+
x === Other(1) // error
67+
Other(2) === x // error
68+
z === Some(n) // error
69+
z === n // error
70+
Some(n) === z // error
71+
n === z // error
72+
Other(1) === z // error
73+
z === Other(1) // error
74+
ddistinct(List(z, n)) // error
75+
}
76+
}

0 commit comments

Comments
 (0)