1
+ package test
2
+
3
+ import annotation .showAsInfix
4
+
5
+ class TypeLevel {
6
+ type Tuple
7
+ type Empty <: Tuple
8
+ type Pair [+ H , + T <: Tuple ] <: Tuple
9
+ erased def erasedValue [T ]: T = ???
10
+ case class Typed [T ](val value : T ) { type Type = T }
11
+ }
12
+
13
+ object Tuples {
14
+ val typelevel = new TypeLevel
15
+ import typelevel ._
16
+
17
+ transparent def _empty : typelevel.Tuple = erasedValue[Empty ]
18
+ transparent def _pair [H , T <: typelevel.Tuple ] (x : H , xs : T ): typelevel.Tuple = erasedValue[Pair [H , T ]]
19
+
20
+ transparent def _size (xs : typelevel.Tuple ): Int = xs match {
21
+ case _ : typelevel.Empty => 0
22
+ case _ : typelevel.Pair [x1, xs1] => _size(erasedValue[xs1]) + 1
23
+ }
24
+
25
+ val x = _size(erasedValue[Pair [Int , Pair [String , Empty ]]])
26
+ /*
27
+ transparent def _index(xs: Tuple, n: Int): Any = xs match {
28
+ case x *: _ if n == 0 => x
29
+ case _ *: xs1 if n > 0 => _index(xs1, n - 1)
30
+ }
31
+
32
+ class TupleOps(val xs: Tuple) extends AnyVal {
33
+
34
+ transparent def *: [H] (x: H): Tuple = new *:(x, xs)
35
+ transparent def size: Int = _size(xs)
36
+
37
+ transparent def apply(n: Int): Any = {
38
+ erased val typed = Typed(_index(xs, n))
39
+ val result = _size(xs) match {
40
+ case 1 =>
41
+ n match {
42
+ case 1 => xs.asInstanceOf[Tuple1[_]].__1
43
+ }
44
+ case 2 =>
45
+ n match {
46
+ case 1 => xs.asInstanceOf[Tuple2[_, _]].__1
47
+ case 2 => xs.asInstanceOf[Tuple2[_, _]].__2
48
+ }
49
+ case 3 =>
50
+ n match {
51
+ case 1 => xs.asInstanceOf[Tuple3[_, _, _]].__1
52
+ case 2 => xs.asInstanceOf[Tuple3[_, _, _]].__2
53
+ case 3 => xs.asInstanceOf[Tuple3[_, _, _]].__3
54
+ }
55
+ case 4 =>
56
+ n match {
57
+ case 1 => xs.asInstanceOf[Tuple4[_, _, _, _]].__1
58
+ case 2 => xs.asInstanceOf[Tuple4[_, _, _, _]].__2
59
+ case 3 => xs.asInstanceOf[Tuple4[_, _, _, _]].__3
60
+ case 4 => xs.asInstanceOf[Tuple4[_, _, _, _]].__4
61
+ }
62
+ }
63
+ result.asInstanceOf[typed.Type]
64
+ }
65
+ transparent def **: (ys: Tuple): Tuple = ys match {
66
+ case Empty => xs
67
+ case y *: ys1 => y *: (ys1 **: xs)
68
+ }
69
+ transparent def head = xs match {
70
+ case x *: _ => x
71
+ }
72
+ transparent def tail = xs match {
73
+ case _ *: xs => xs
74
+ }
75
+ }
76
+
77
+ val emptyArray = Array[Object]()
78
+
79
+ transparent def toObj(t: Any) = t.asInstanceOf[Object]
80
+
81
+ transparent def toArray(t: Tuple): Array[Object] = t.size match {
82
+ case 0 => emptyArray
83
+ case 1 => Array(toObj(t(0)))
84
+ case 2 => Array(toObj(t(0)), toObj(t(1)))
85
+ case 3 => Array(toObj(t(0)), toObj(t(1)), toObj(t(2)))
86
+ case 4 => Array(toObj(t(0)), toObj(t(1)), toObj(t(2)), toObj(t(3)))
87
+ }
88
+
89
+ transparent implicit def tupleDeco(xs: Tuple): TupleOps = new TupleOps(xs)
90
+
91
+ transparent def apply(): Tuple = Empty
92
+ transparent def apply(x1: Any): Tuple = x1 *: Empty
93
+ transparent def apply(x1: Any, x2: Any) = x1 *: x2 *: Empty
94
+ transparent def apply(x1: Any, x2: Any, x3: Any) = x1 *: x2 *: x3 *: Empty
95
+
96
+ val xs0 = Tuple()
97
+ val xs1 = Tuple(2)
98
+ val xs2 = Tuple(2, "a")
99
+ val xs3 = Tuple(true, 1, 2.0)
100
+ transparent val s0 = xs0.size; val s0c: 0 = s0
101
+ transparent val s1 = xs1.size; val s1c: 1 = s1
102
+ transparent val s2 = xs2.size; val s2c: 2 = s2
103
+ transparent val s3 = xs3.size; val s3c: 3 = s3
104
+ val e0 = xs3(0); val e0c: Boolean = e0
105
+ val e1 = xs3(1); val e1c: Int = e1
106
+ val e2 = xs3(2); val e2c: Double = e2
107
+
108
+ val conc0 = xs0 **: xs3
109
+ val conc1 = xs3 **: xs0
110
+ val conc2 = xs2 **: xs3
111
+ val e3c: Int = conc0(1)
112
+ val e4c: Int = conc1(1)
113
+ val e5c: Int = conc2(0)
114
+ val e6c: Double = conc2(4)
115
+ */
116
+ }
117
+ /*
118
+ class Tuple1[+T1](val __1: T1) extends *:(__1, Empty)
119
+ class Tuple2[+T1, +T2](val __1: T1, val __2: T2) extends *:(__1, *:(__2, Empty))
120
+ class Tuple3[+T1, +T2, +T3](val __1: T1, val __2: T2, val __3: T3) extends *:(__1, *:(__2, *:(__3, Empty)))
121
+ class Tuple4[+T1, +T2, +T3, +T4](val __1: T1, val __2: T2, val __3: T3, val __4: T4) extends *:(__1, *:(__2, *:(__3, *:(__4, Empty))))
122
+
123
+ object Test extends App
124
+ */
0 commit comments