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
|
package namedparams
class C[type Elem, type Value](val elem: Elem) {
def toVal: Elem = ???
}
class D[type Elem, V](elem: Elem) extends C[Elem, V](elem)
object Test {
val c = new C[String, String]("A") {
override def toVal = elem
}
val x: c.Elem = c.elem
val c2: C { type Elem = String } = c
val c3 = new C[Elem = String, Value = Int]("B")
val c4 = new C[Elem = String]("C")
val x2: c2.Elem = c2.elem
def d1[E, V](x: E) = new D[E, V](x)
def d2[E, V](x: E) = new C[Elem = E, Value = V](x)
val y1 = d1[Int, String](1)
val y2 = d1[E = Int](2)
val y3 = d1[V = String](3)
val z1 = d2[E = Int, V = String](1)
val z2 = d2[V = String, E = Int](1)
val z3 = d2[E = Int](1)
val z4 = d2[V = Int]("AAA")
val z5 = d2[E = Int][V = String](1)
// Testing type inference
def f[X <: C](x: X[Int, Int]): X[String, String] = ???
val arg1: C[Int, Int] = ???
val res1 = f(arg1)
val chk1: C[String, String] = res1
class C1[type Elem, type Value](x: Elem) extends C[Elem, Value](x)
class CC extends C1[Int, Int](1)
val arg2: CC = ???
val res2 = f(arg2)
val chk2: C[String, String] = res2
class D1[type Elem, type Value](x: Elem) extends C[Elem, Value](x)
class DD extends D1[Int, Int](2)
val arg3: CC & DD = ???
val res3 = f(arg3)
val chk3: (C1 & D1) { type Elem = String; type Value = String } = res3
val arg4: CC | DD = ???
val res4 = f(arg4)
val chk4: C[String, String] = ???
class CX[type Elem](x: Elem) extends C1[Elem, Int](x)
class DX[type Value]() extends D1[Int, Value](2)
val arg5: CX[Int] & DX[Int] = ???
val res5 = f(arg5)
val chk5: (C1 & D1) { type Elem = String; type Value = String } = res5
val chk6: C1[String, String] & D1[String, String] = chk5
val chk7: (C1 & D1) { type Elem = String; type Value = String } = chk6
}
// Adapted from i94-nada, somewhat non-sensical
trait Test1 {
trait Monad[type Elem] {
def unit: Elem
}
sealed abstract class Either[A,B]
case class Left[A,B](unit: A) extends Either[A,B] with Monad[A]
case class Right[A,B](unit: B) extends Either[A,B] with Monad[B]
def flatMap[X,Y,M <: Monad](m: M[Elem = X], f: X => M[Elem = Y]): M[Elem = Y] = f(m.unit)
val res = flatMap(Left(1), {x: Int => Left(x)})
val chk: Either[Int, Nothing] & Monad & Product1[Int] = res
}
// Adapted from i94-nada, this time with more sense
trait Test2 {
trait Monad[type Elem] {
def unit: Elem
}
sealed abstract class Either[A,B]
case class Left[type Elem, B](unit: Elem) extends Either[Elem,B] with Monad[Elem]
case class Right[A, type Elem](unit: Elem) extends Either[A,Elem] with Monad[Elem]
def flatMap[X,Y,M <: Monad](m: M[Elem = X], f: X => M[Elem = Y]): M[Elem = Y] = f(m.unit)
val res = flatMap(Left(1), {x: Int => Left(x)})
val chk: Left[Int, Nothing] = res
}
|