1+ package test {
2+
3+ import annotation .showAsInfix
4+
5+ object typelevel {
6+ erased def erasedValue [T ]: T = ???
7+ case class Typed [T ](val value : T ) { type Type = T }
8+ }
9+
10+ sealed trait Tuple
11+ object Empty extends Tuple
12+
13+ @ showAsInfix
14+ case class *: [+ H , + T <: Tuple ](hd : H , tl : T ) extends Tuple
15+
16+ object Tuple {
17+ import typelevel ._
18+ type Empty = Empty .type
19+
20+ transparent def _cons [H , T <: Tuple ] (x : H , xs : T ): Tuple = new *: (x, xs)
21+
22+ transparent def _size (xs : Tuple ): Int = xs match {
23+ case Empty => 0
24+ case _ *: xs1 => _size(xs1) + 1
25+ }
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+ }
124+
125+ object Test extends App
0 commit comments