1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
object equality {
trait Eq[T, U]
def Eq[T, U]: Eq[T, U] = new Eq[T, U]{}
implicit class EqualsDeco[T](val x: T) extends AnyVal {
def ===[U] (y: U)(implicit ce: Eq[T, U]) = x.equals(y)
}
type EqEq[T] = Eq[T, T]
trait EqClass[T]
implicit def eqAny[T, U]: Eq[T, U] = Eq
/*
implicit def mixedEq1[T, U](implicit ce: Eq[T, U]): Eq[T, Any] = Eq
implicit def mixedEq2[T, U](implicit ce: Eq[T, U]): Eq[Any, T] = Eq
implicit def mixedEq1alt : Eq[Any, EqClass] = Eq
implicit def mixedEq2 : Eq[EqClass, Any] = Eq
implicit def mixedEq2alt : Eq[EqClass, Any] = Eq
implicit def mixedNull1[T]: Eq[T, Null] = Eq
implicit def mixedNull2[T]: Eq[Null, T] = Eq
*/
implicit def eqString: Eq[String, String] = Eq
implicit def eqInt: Eq[Int, Int] = Eq
implicit def eqOption[T, U](implicit ce: Eq[T, U]): Eq[Option[T], Option[U]] = Eq
/*
implicit def eqEq[UE, TE <: UE with EqClass[UE]]: Eq[TE, TE] = Eq
case class Str(str: String) extends EqClass[Str]
case class Num(x: Int) extends EqClass[Num]
case class Other(x: Int)
trait Option[+T] extends EqClass[_]
case class Some[+T](x: T) extends Option[T]
case object None extends Option[Nothing]
//implicit def eqStr: Eq[Str, Str] = Eq
//implicit def eqNum: Eq[Num, Num] = Eq
implicit def eqOption[T, U](implicit ce: Eq[T, U]): Eq[Option[T], Option[U]] = Eq
*/
def some[T](x: T): Option[T] = Some(x)
def main(args: Array[String]): Unit = {
val x = "abc"
x === x
val n = 2
n === n
x === 1 // error
n === x // error
1.0 === 1.0
1.0 === new Object
1.0 === n // error
some(n) === some(n)
some(n) === 1 // error
some(n) === some(1) // error
1 === some(n) // error
some(1) === some(n)
some(1.0) === some(new Object)
some(1) === some(x) // error
some(x) === some(1) // error
some(x) === some(1.0)
/*
val n = Num(2)
val m = Num(3)
n === m
Other(1) === Other(2)
Some(x) === Some(Str(""))
val z: Option[Str] = Some(Str("abc"))
z === Some(x)
z === None
Some(x) === z
None === z
Some(Other(1)) === None
Other(3) === null
Str("x") === null
// null === Other(3)
// null === Str("x")
// null === null
class Fruit extends EqClass
class Apple extends Fruit
class Pear extends Fruit
implicit def eqFruit: Eq[Fruit, Fruit] = Eq
Some(new Apple) === Some(new Pear)
def ddistinct[T: EqEq](xs: List[T]): List[T] = xs match {
case Nil => Nil
case x :: xs => x :: xs.filterNot(x === _)
}
ddistinct(List(z, z, z))
n match {
case None =>
}
Some(new Apple) === Some(Str("xx")) // error
Some(new Apple) === Some(Other(1)) // error
Some(Other(1)) === Some(new Apple) // error
x === n // error
n === x // error
x === Other(1) // error
Other(2) === x // error
z === Some(n) // error
z === n // error
Some(n) === z // error
n === z // error
Other(1) === z // error
z === Other(1) // error
ddistinct(List(z, n)) // error
*/
}
}
|