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