1- package test
1+ package test {
22
33import annotation .showAsInfix
44
55class TypeLevel {
66 type Tuple
77 type Empty <: Tuple
8- type Pair [+ H , + T <: Tuple ] <: Tuple
8+
9+ @ showAsInfix type *: [+ H , + T <: Tuple ] <: Tuple
910 erased def erasedValue [T ]: T = ???
1011 case class Typed [T ](val value : T ) { type Type = T }
1112}
1213
14+ class TupleXXL (val elems : Array [Object ])
15+
1316object Tuples {
1417 val typelevel = new TypeLevel
1518 import typelevel ._
1619
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 ]]
20+ final val MaxSpecialized = 7 // 22 in real life
21+
22+ transparent def _empty : Tuple = erasedValue[Empty ]
23+ transparent def _pair [H , T <: Tuple ] (x : H , xs : T ): Tuple = erasedValue[H *: T ]
24+
25+ def unit = ().asInstanceOf [Empty ]
1926
20- transparent def _size (xs : typelevel. Tuple ): Int = xs match {
21- case _ : typelevel. Empty => 0
22- case _ : typelevel. Pair [_, xs1] => _size(erasedValue[xs1]) + 1
27+ transparent def _size (xs : Tuple ): Int = xs match {
28+ case _ : Empty => 0
29+ case _ : (_ *: xs1) => _size(erasedValue[xs1]) + 1
2330 }
2431
25- val x = _size(erasedValue[Pair [Int , Pair [String , Empty ]]])
26- /*
32+ erased val xs2 = erasedValue[Int *: String *: Empty ]
33+
34+ erased val s = _size(xs2)
35+
2736 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)
37+ case _ : (x *: _) if n == 0 => erasedValue[x]
38+ case _ : (_ *: xs1) if n > 0 => _index(erasedValue[xs1], n - 1 )
39+ }
40+
41+ transparent def _head (xs : Tuple ): Any = xs match {
42+ case _ : (x *: _) => erasedValue[x]
3043 }
3144
45+ transparent def _tail (xs : Tuple ): Tuple = xs match {
46+ case _ : (_ *: xs1) => erasedValue[xs1]
47+ }
48+
49+ transparent def _concat (xs : Tuple , ys : Tuple ): Tuple = xs match {
50+ case _ : Empty => ys
51+ case _ : (x1 *: xs1) => _pair(erasedValue[x1], _concat(erasedValue[xs1], ys))
52+ }
53+
54+ erased val e0 = _index(xs2, 0 )
55+ erased val e1 = _index(xs2, 1 )
56+
57+ transparent def fromArray [T <: Tuple ](xs : Array [Object ]): T =
58+ _size(erasedValue[T ]) match {
59+ case 0 => ().asInstanceOf [T ]
60+ case 1 => Tuple1 (xs(0 )).asInstanceOf [T ]
61+ case 2 => Tuple2 (xs(0 ), xs(1 )).asInstanceOf [T ]
62+ case 3 => Tuple3 (xs(0 ), xs(1 ), xs(2 )).asInstanceOf [T ]
63+ case 4 => Tuple4 (xs(0 ), xs(1 ), xs(2 ), xs(3 )).asInstanceOf [T ]
64+ case 5 => Tuple5 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 )).asInstanceOf [T ]
65+ case 6 => Tuple6 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 )).asInstanceOf [T ]
66+ case 7 => Tuple7 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 )).asInstanceOf [T ]
67+ case _ => new TupleXXL (xs).asInstanceOf [T ]
68+ }
69+
70+ val emptyArray = Array [Object ]()
71+
72+ transparent implicit def tupleDeco (xs : Tuple ): TupleOps = new TupleOps (xs)
73+
3274 class TupleOps (val xs : Tuple ) extends AnyVal {
3375
34- transparent def *: [H] (x: H): Tuple = new *:(x, xs)
35- transparent def size: Int = _size(xs)
76+ transparent def toArray : Array [Object ] = _size(xs) match {
77+ case 0 =>
78+ emptyArray
79+ case 1 =>
80+ val t = xs.asInstanceOf [Tuple1 [Object ]]
81+ Array (t._1)
82+ case 2 =>
83+ val t = xs.asInstanceOf [Tuple2 [Object , Object ]]
84+ Array (t._1, t._2)
85+ case 3 =>
86+ val t = xs.asInstanceOf [Tuple3 [Object , Object , Object ]]
87+ Array (t._1, t._2, t._3)
88+ case 4 =>
89+ val t = xs.asInstanceOf [Tuple4 [Object , Object , Object , Object ]]
90+ Array (t._1, t._2, t._3, t._4)
91+ case 5 =>
92+ val t = xs.asInstanceOf [Tuple5 [Object , Object , Object , Object , Object ]]
93+ Array (t._1, t._2, t._3, t._4, t._5)
94+ case 6 =>
95+ val t = xs.asInstanceOf [Tuple6 [Object , Object , Object , Object , Object , Object ]]
96+ Array (t._1, t._2, t._3, t._4, t._5, t._6)
97+ case 7 =>
98+ val t = xs.asInstanceOf [Tuple7 [Object , Object , Object , Object , Object , Object , Object ]]
99+ Array (t._1, t._2, t._3, t._4, t._5, t._6, t._7)
100+ case _ =>
101+ xs.asInstanceOf [TupleXXL ].elems
102+ }
103+
104+ transparent def *: [H ] (x : H ): Tuple = {
105+ erased val resTpe = Typed (_pair(x, xs))
106+ _size(xs) match {
107+ case 0 =>
108+ Tuple1 (x).asInstanceOf [resTpe.Type ]
109+ case 1 =>
110+ Tuple2 (x, xs.asInstanceOf [Tuple1 [_]]._1).asInstanceOf [resTpe.Type ]
111+ case 2 =>
112+ val t = xs.asInstanceOf [Tuple2 [_, _]]
113+ Tuple3 (x, t._1, t._2).asInstanceOf [resTpe.Type ]
114+ case 3 =>
115+ val t = xs.asInstanceOf [Tuple3 [_, _, _]]
116+ Tuple4 (x, t._1, t._2, t._3).asInstanceOf [resTpe.Type ]
117+ case 4 =>
118+ val t = xs.asInstanceOf [Tuple4 [_, _, _, _]]
119+ Tuple5 (x, t._1, t._2, t._3, t._4).asInstanceOf [resTpe.Type ]
120+ case n =>
121+ fromArray[resTpe.Type ](prepend(x, toArray))
122+ }
123+ }
124+
125+ private def prepend [H ](x : H , elems : Array [Object ]): Array [Object ] = {
126+ val elems1 = new Array [Object ](elems.length + 1 )
127+ elems1(0 ) = x.asInstanceOf [Object ]
128+ Array .copy(elems, 0 , elems1, 1 , elems.length)
129+ elems1
130+ }
131+
132+ transparent def head : Any = {
133+ erased val resTpe = Typed (_head(xs))
134+ _size(xs) match {
135+ case 1 =>
136+ val t = xs.asInstanceOf [Tuple1 [_]]
137+ t._1.asInstanceOf [resTpe.Type ]
138+ case 2 =>
139+ val t = xs.asInstanceOf [Tuple2 [_, _]]
140+ t._1.asInstanceOf [resTpe.Type ]
141+ case 3 =>
142+ val t = xs.asInstanceOf [Tuple3 [_, _, _]]
143+ t._1.asInstanceOf [resTpe.Type ]
144+ case 4 =>
145+ val t = xs.asInstanceOf [Tuple4 [_, _, _, _]]
146+ t._1.asInstanceOf [resTpe.Type ]
147+ case n if n > 4 && n <= MaxSpecialized =>
148+ xs.asInstanceOf [Product ].productElement(0 ).asInstanceOf [resTpe.Type ]
149+ case n if n > MaxSpecialized =>
150+ val t = xs.asInstanceOf [TupleXXL ]
151+ t.elems(0 ).asInstanceOf [resTpe.Type ]
152+ }
153+ }
154+
155+ transparent def tail : Any = {
156+ erased val resTpe = Typed (_tail(xs))
157+ _size(xs) match {
158+ case 1 =>
159+ unit
160+ case 2 =>
161+ val t = xs.asInstanceOf [Tuple2 [_, _]]
162+ Tuple1 (t._2).asInstanceOf [resTpe.Type ]
163+ case 3 =>
164+ val t = xs.asInstanceOf [Tuple3 [_, _, _]]
165+ Tuple2 (t._2, t._3).asInstanceOf [resTpe.Type ]
166+ case 4 =>
167+ val t = xs.asInstanceOf [Tuple4 [_, _, _, _]]
168+ Tuple3 (t._2, t._3, t._4).asInstanceOf [resTpe.Type ]
169+ case 5 =>
170+ val t = xs.asInstanceOf [Tuple5 [_, _, _, _, _]]
171+ Tuple4 (t._2, t._3, t._4, t._5).asInstanceOf [resTpe.Type ]
172+ case n if n > 5 =>
173+ fromArray[resTpe.Type ](toArray.tail)
174+ }
175+ }
36176
37177 transparent def apply (n : Int ): Any = {
38- erased val typed = Typed(_index(xs, n))
39- val result = _size(xs) match {
178+ erased val resTpe = Typed (_index(xs, n))
179+ _size(xs) match {
40180 case 1 =>
181+ val t = xs.asInstanceOf [Tuple1 [_]]
41182 n match {
42- case 1 => xs. asInstanceOf[Tuple1[_]].__1
183+ case 0 => t._1. asInstanceOf [resTpe. Type ]
43184 }
44185 case 2 =>
186+ val t = xs.asInstanceOf [Tuple2 [_, _]]
45187 n match {
46- case 1 => xs. asInstanceOf[Tuple2[_, _]].__1
47- case 2 => xs. asInstanceOf[Tuple2[_, _]].__2
188+ case 0 => t._1. asInstanceOf [resTpe. Type ]
189+ case 1 => t._2. asInstanceOf [resTpe. Type ]
48190 }
49191 case 3 =>
192+ val t = xs.asInstanceOf [Tuple3 [_, _, _]]
50193 n match {
51- case 1 => xs. asInstanceOf[Tuple3[_, _, _]].__1
52- case 2 => xs. asInstanceOf[Tuple3[_, _, _]].__2
53- case 3 => xs. asInstanceOf[Tuple3[_, _, _]].__3
194+ case 0 => t._1. asInstanceOf [resTpe. Type ]
195+ case 1 => t._2. asInstanceOf [resTpe. Type ]
196+ case 2 => t._3. asInstanceOf [resTpe. Type ]
54197 }
55198 case 4 =>
199+ val t = xs.asInstanceOf [Tuple4 [_, _, _, _]]
56200 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
201+ case 0 => t._1. asInstanceOf [resTpe. Type ]
202+ case 1 => t._2. asInstanceOf [resTpe. Type ]
203+ case 2 => t._3. asInstanceOf [resTpe. Type ]
204+ case 3 => t._4. asInstanceOf [resTpe. Type ]
61205 }
206+ case s if s > 4 && s <= MaxSpecialized && n >= 0 && n < s =>
207+ xs.asInstanceOf [Product ].productElement(n).asInstanceOf [resTpe.Type ]
208+ case s if s > MaxSpecialized && n >= 0 && n < s =>
209+ xs.asInstanceOf [TupleXXL ].elems(n).asInstanceOf [resTpe.Type ]
62210 }
63- result.asInstanceOf[typed.Type]
64211 }
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- }
76212
77- val emptyArray = Array[Object]()
78-
79- transparent def toObj(t: Any) = t.asInstanceOf[Object]
213+ transparent def ++ (ys : Tuple ): Tuple = {
214+ erased val resTpe = Typed (_concat(xs, ys))
215+ _size(xs) match {
216+ case 0 => ys
217+ case 1 =>
218+ if (_size(ys) == 0 ) xs
219+ else xs.head *: ys
220+ case 2 =>
221+ val t = xs.asInstanceOf [Tuple2 [_, _]]
222+ _size(ys) match {
223+ case 0 => xs
224+ case 1 =>
225+ val u = ys.asInstanceOf [Tuple1 [_]]
226+ Tuple3 (t._1, t._2, u._1).asInstanceOf [resTpe.Type ]
227+ case 2 =>
228+ val u = ys.asInstanceOf [Tuple2 [_, _]]
229+ Tuple4 (t._1, t._2, u._1, u._2).asInstanceOf [resTpe.Type ]
230+ case _ =>
231+ genericConcat[resTpe.Type ](xs, ys)
232+ }
233+ case 3 =>
234+ val t = xs.asInstanceOf [Tuple3 [_, _, _]]
235+ _size(ys) match {
236+ case 0 => xs
237+ case 1 =>
238+ val u = ys.asInstanceOf [Tuple1 [_]]
239+ Tuple4 (t._1, t._2, t._3, u._1).asInstanceOf [resTpe.Type ]
240+ case _ =>
241+ genericConcat[resTpe.Type ](xs, ys)
242+ }
243+ case _ =>
244+ if (_size(ys) == 0 ) xs
245+ else genericConcat[resTpe.Type ](xs, ys)
246+ }
247+ }
80248
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)))
249+ transparent def genericConcat [T <: Tuple ](xs : Tuple , ys : Tuple ): Tuple =
250+ fromArray[T ](xs.toArray ++ ys.toArray)
87251 }
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- */
116252}
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- */
253+ }
254+ object Test extends App {
255+ import test ._
256+ import Tuples ._
257+ import typelevel ._
258+ val x0 = unit
259+ val x1 = 1 *: x0
260+ val x2 = " A" *: x1
261+ val x3 = 2 *: x2
262+ val x4 = " B" *: x3
263+ val x5 = 3 *: x4
264+ val x6 = " C" *: x5
265+ val x7 = 4 *: x6
266+ val x8 = " D" *: x7
267+ val h1 = x1.head; val h1c : Int = h1
268+ val h2 = x2.head; val h2c : String = h2
269+ val h7 = x7.head; val h7c : Int = h7
270+ val h8 = x8.head; val h8c : String = h8
271+ val t1 = x1.tail; val t1c : Empty = t1
272+ val t2 = x2.tail; val t2c : Int *: Empty = t2
273+ val t7 = x7.tail; val t7c : String *: Int *: Empty = t7.tail.tail.tail.tail
274+ val t8 = x8.tail; val t8c : Int = t8(6 )
275+ val a1_0 = x1(0 ); val a1_0c : Int = a1_0
276+ val a2_0 = x2(0 ); val a2_0c : String = a2_0
277+ val a3_1 = x3(1 ); val a3_1c : String = a3_1
278+ val a4_3 = x4(3 ); val a4_3c : Int = a4_3
279+ val a6_4 = x6(4 ); val a6_4c : String = a6_4
280+ val a8_0 = x8(0 ); val a8_0c : String = a8_0
281+ val c0_0 = x0 ++ x0; val c0_0c : Empty = c0_0
282+ val c0_1 = x0 ++ x1; val c0_1c : Int *: Empty = c0_1c
283+ val c1_0 = x1 ++ x0; val c1_0c : Int *: Empty = c1_0c
284+ val c0_4 = x0 ++ x4; val c0_4c : String *: Int *: String *: Int *: Empty = c0_4
285+ val c4_0 = x4 ++ x0; val c4_0c : String *: Int *: String *: Int *: Empty = c4_0
286+ val c1_1 = x1 ++ x1; val c1_1c : Int *: Int *: Empty = c1_1
287+ val c1_8 = x1 ++ x8; val c1_8c : Int *: String *: Int *: String *: Int *: String *: Int *: String *: Int *: Empty = c1_8
288+ val c2_1 = x2 ++ x1; val c2_1c : String *: Int *: Int *: Empty = c2_1
289+ val c2_2 = x2 ++ x2; val c2_2c : String *: Int *: String *: Int *: Empty = c2_2
290+ val c2_3 = x2 ++ x3; val c2_3c : String *: Int *: Int *: String *: Int *: Empty = c2_3
291+ val c3_3 = x3 ++ x3; val c3_3c : Int *: String *: Int *: Int *: String *: Int *: Empty = c3_3
292+ }
0 commit comments