@@ -4,56 +4,63 @@ import annotation.showAsInfix
4
4
5
5
class TypeLevel {
6
6
type Tuple
7
+
7
8
type Empty <: Tuple
9
+ // in the actual implementation, pick scala.Unit, and have it extend `Tuple`.
8
10
9
11
@ showAsInfix type *: [+ H , + T <: Tuple ] <: Tuple
12
+
10
13
erased def erasedValue [T ]: T = ???
11
14
case class Typed [T ](val value : T ) { type Type = T }
12
15
}
13
16
14
- class TupleXXL (val elems : Array [Object ])
17
+ class TupleXXL private (es : Array [Object ]) {
18
+ override def toString = elems.mkString(" (" , " ," , " )" )
19
+ override def hashCode = getClass.hashCode * 41 + elems.deep.hashCode
20
+ override def equals (that : Any ) = that match {
21
+ case that : TupleXXL => this .elems.deep.equals(that.elems.deep)
22
+ case _ => false
23
+ }
24
+ def elems : Array [Object ] = es
25
+ }
26
+ object TupleXXL {
27
+ def apply (elems : Array [Object ]) = new TupleXXL (elems.clone)
28
+ }
15
29
16
30
object Tuples {
17
31
val typelevel = new TypeLevel
18
32
import typelevel ._
19
33
20
- final val MaxSpecialized = 7 // 22 in real life
34
+ def unit = (). asInstanceOf [ Empty ]
21
35
22
- transparent def _empty : Tuple = erasedValue[Empty ]
23
- transparent def _pair [H , T <: Tuple ] (x : H , xs : T ): Tuple = erasedValue[H *: T ]
36
+ private final val MaxSpecialized = 7 // 22 in real life
24
37
25
- def unit = ().asInstanceOf [Empty ]
38
+ private transparent def _empty : Tuple = erasedValue[Empty ]
39
+ private transparent def _pair [H , T <: Tuple ] (x : H , xs : T ): Tuple = erasedValue[H *: T ]
26
40
27
- transparent def _size (xs : Tuple ): Int = xs match {
41
+ private transparent def _size (xs : Tuple ): Int = xs match {
28
42
case _ : Empty => 0
29
43
case _ : (_ *: xs1) => _size(erasedValue[xs1]) + 1
30
44
}
31
45
32
- erased val xs2 = erasedValue[Int *: String *: Empty ]
33
-
34
- erased val s = _size(xs2)
35
-
36
- transparent def _index (xs : Tuple , n : Int ): Any = xs match {
46
+ private transparent def _index (xs : Tuple , n : Int ): Any = xs match {
37
47
case _ : (x *: _) if n == 0 => erasedValue[x]
38
48
case _ : (_ *: xs1) if n > 0 => _index(erasedValue[xs1], n - 1 )
39
49
}
40
50
41
- transparent def _head (xs : Tuple ): Any = xs match {
51
+ private transparent def _head (xs : Tuple ): Any = xs match {
42
52
case _ : (x *: _) => erasedValue[x]
43
53
}
44
54
45
- transparent def _tail (xs : Tuple ): Tuple = xs match {
55
+ private transparent def _tail (xs : Tuple ): Tuple = xs match {
46
56
case _ : (_ *: xs1) => erasedValue[xs1]
47
57
}
48
58
49
- transparent def _concat (xs : Tuple , ys : Tuple ): Tuple = xs match {
59
+ private transparent def _concat (xs : Tuple , ys : Tuple ): Tuple = xs match {
50
60
case _ : Empty => ys
51
61
case _ : (x1 *: xs1) => _pair(erasedValue[x1], _concat(erasedValue[xs1], ys))
52
62
}
53
63
54
- erased val e0 = _index(xs2, 0 )
55
- erased val e1 = _index(xs2, 1 )
56
-
57
64
transparent def fromArray [T <: Tuple ](xs : Array [Object ]): T =
58
65
_size(erasedValue[T ]) match {
59
66
case 0 => ().asInstanceOf [T ]
@@ -64,7 +71,7 @@ object Tuples {
64
71
case 5 => Tuple5 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 )).asInstanceOf [T ]
65
72
case 6 => Tuple6 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 )).asInstanceOf [T ]
66
73
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 ]
74
+ case _ => TupleXXL (xs).asInstanceOf [T ]
68
75
}
69
76
70
77
val emptyArray = Array [Object ]()
@@ -255,38 +262,38 @@ object Test extends App {
255
262
import test ._
256
263
import Tuples ._
257
264
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
265
+ val x0 = unit; println(x0)
266
+ val x1 = 1 *: x0; println(x1)
267
+ val x2 = " A" *: x1; println(x2)
268
+ val x3 = 2 *: x2; println(x3)
269
+ val x4 = " B" *: x3; println(x4)
270
+ val x5 = 3 *: x4; println(x5)
271
+ val x6 = " C" *: x5; println(x6)
272
+ val x7 = 4 *: x6; println(x7)
273
+ val x8 = " D" *: x7; println(x8)
274
+ val h1 = x1.head; val h1c : Int = h1; println( s " h1 = $h1 " )
275
+ val h2 = x2.head; val h2c : String = h2; println( s " h2 = $h2 " )
276
+ val h7 = x7.head; val h7c : Int = h7; println( s " h7 = $h7 " )
277
+ val h8 = x8.head; val h8c : String = h8; println( s " h8 = $h8 " )
278
+ val t1 = x1.tail; val t1c : Empty = t1; println( s " t1 = $t1 " )
279
+ val t2 = x2.tail; val t2c : Int *: Empty = t2; println( s " t2 = $t2 " )
280
+ val t7 = x7.tail; val t7c : String *: Int *: Empty = t7.tail.tail.tail.tail; println( s " t7 = $t7 " )
281
+ val t8 = x8.tail; val t8c : Int = t8(6 ); println( s " t8 = $t8 " )
282
+ val a1_0 = x1(0 ); val a1_0c : Int = a1_0; println( s " a1_0 = $a1_0 " )
283
+ val a2_0 = x2(0 ); val a2_0c : String = a2_0; println( s " a2_0 = $a2_0 " )
284
+ val a3_1 = x3(1 ); val a3_1c : String = a3_1; println( s " a3_1 = $a3_1 " )
285
+ val a4_3 = x4(3 ); val a4_3c : Int = a4_3; println( s " a4_3 = $a4_3 " )
286
+ val a6_4 = x6(4 ); val a6_4c : String = a6_4; println( s " a6_4 = $a6_4 " )
287
+ val a8_0 = x8(0 ); val a8_0c : String = a8_0; println( s " a8_0 = $a8_0 " )
288
+ val c0_0 = x0 ++ x0; val c0_0c : Empty = c0_0; println( s " c0_0 = $c0_0 " )
289
+ val c0_1 = x0 ++ x1; val c0_1c : Int *: Empty = c0_1c; println( s " c0_1 = $c0_1 " )
290
+ val c1_0 = x1 ++ x0; val c1_0c : Int *: Empty = c1_0c; println( s " c1_0 = $c1_0 " )
291
+ val c0_4 = x0 ++ x4; val c0_4c : String *: Int *: String *: Int *: Empty = c0_4; println( s " c0_4 = $c0_4 " )
292
+ val c4_0 = x4 ++ x0; val c4_0c : String *: Int *: String *: Int *: Empty = c4_0; println( s " c4_0 = $c4_0 " )
293
+ val c1_1 = x1 ++ x1; val c1_1c : Int *: Int *: Empty = c1_1; println( s " c1_1 = $c1_1 " )
294
+ val c1_8 = x1 ++ x8; val c1_8c : Int *: String *: Int *: String *: Int *: String *: Int *: String *: Int *: Empty = c1_8; println( s " c1_8 = $c1_8 " )
295
+ val c2_1 = x2 ++ x1; val c2_1c : String *: Int *: Int *: Empty = c2_1; println( s " c2_1 = $c2_1 " )
296
+ val c2_2 = x2 ++ x2; val c2_2c : String *: Int *: String *: Int *: Empty = c2_2; println( s " c2_2 = $c2_2 " )
297
+ val c2_3 = x2 ++ x3; val c2_3c : String *: Int *: Int *: String *: Int *: Empty = c2_3; println( s " c2_3 = $c2_3 " )
298
+ val c3_3 = x3 ++ x3; val c3_3c : Int *: String *: Int *: Int *: String *: Int *: Empty = c3_3; println( s " c3_3 = $c3_3 " )
292
299
}
0 commit comments