Skip to content

Commit 488b3d5

Browse files
committed
Add generative operations to tuples
1 parent 6445f85 commit 488b3d5

File tree

7 files changed

+206
-18
lines changed

7 files changed

+206
-18
lines changed

library/src-scala2/scala/Tuple.scala

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@ package scala
22
import annotation.showAsInfix
33

44
sealed trait Tuple extends Any
5+
object Tuple
56

67
@showAsInfix
7-
sealed class *:[+H, +T <: Tuple] extends Tuple {
8-
def head: H = ???
9-
def tail: T = ???
10-
}
8+
sealed class *:[+H, +T <: Tuple] extends Tuple
119

12-
object *: {
13-
def unapply[H, T <: Tuple](x: H *: T) = Some((x.head, x.tail))
14-
}
10+
object *:

library/src-scala3/scala/Tuple.scala

Lines changed: 133 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,147 @@
11
package scala
22
import annotation.showAsInfix
3+
import typelevel._
4+
5+
sealed trait Tuple extends Any {
6+
import Tuple._
7+
rewrite def toArray: Array[Object] = rewrite _size(this) match {
8+
case 0 =>
9+
$emptyArray
10+
case 1 =>
11+
val t = asInstanceOf[Tuple1[Object]]
12+
Array(t._1)
13+
case 2 =>
14+
val t = asInstanceOf[Tuple2[Object, Object]]
15+
Array(t._1, t._2)
16+
case 3 =>
17+
val t = asInstanceOf[Tuple3[Object, Object, Object]]
18+
Array(t._1, t._2, t._3)
19+
case 4 =>
20+
val t = asInstanceOf[Tuple4[Object, Object, Object, Object]]
21+
Array(t._1, t._2, t._3, t._4)
22+
case n if n <= $MaxSpecialized =>
23+
$toArray(this, n)
24+
case n =>
25+
asInstanceOf[TupleXXL].elems
26+
}
327

4-
object typelevel {
5-
erased def erasedValue[T]: T = ???
28+
rewrite def *: [H] (x: H): Tuple = {
29+
erased val resTpe = Typed(_pair(x, this))
30+
rewrite _size(this) match {
31+
case 0 =>
32+
Tuple1(x).asInstanceOf[resTpe.Type]
33+
case 1 =>
34+
Tuple2(x, asInstanceOf[Tuple1[_]]._1).asInstanceOf[resTpe.Type]
35+
case 2 =>
36+
val t = asInstanceOf[Tuple2[_, _]]
37+
Tuple3(x, t._1, t._2).asInstanceOf[resTpe.Type]
38+
case 3 =>
39+
val t = asInstanceOf[Tuple3[_, _, _]]
40+
Tuple4(x, t._1, t._2, t._3).asInstanceOf[resTpe.Type]
41+
case 4 =>
42+
val t = asInstanceOf[Tuple4[_, _, _, _]]
43+
Tuple5(x, t._1, t._2, t._3, t._4).asInstanceOf[resTpe.Type]
44+
case n =>
45+
fromArray[resTpe.Type]($consArray(x, toArray))
46+
}
47+
}
648
}
749

8-
import typelevel._
50+
object Tuple {
51+
transparent val $MaxSpecialized = 22
952

10-
sealed trait Tuple extends Any
53+
val $emptyArray = Array[Object]()
1154

12-
@showAsInfix
13-
sealed class *:[+H, +T <: Tuple] extends Tuple {
14-
rewrite def head: H = ???
15-
rewrite def tail: T = ???
55+
def $toArray(xs: Tuple, n: Int) = {
56+
val arr = new Array[Object](n)
57+
var i = 0
58+
var it = xs.asInstanceOf[Product].productIterator
59+
while (i < n) {
60+
arr(i) = it.next().asInstanceOf[Object]
61+
i += 1
62+
}
63+
arr
64+
}
65+
66+
def $consArray[H](x: H, elems: Array[Object]): Array[Object] = {
67+
val elems1 = new Array[Object](elems.length + 1)
68+
elems1(0) = x.asInstanceOf[Object]
69+
Array.copy(elems, 0, elems1, 1, elems.length)
70+
elems1
71+
}
1672

17-
rewrite private def _size(xs: Tuple): Int = //rewrite
18-
xs match {
73+
private[scala] rewrite def _pair[H, T <: Tuple] (x: H, xs: T): Tuple =
74+
erasedValue[H *: T]
75+
76+
private[scala] rewrite def _size(xs: Tuple): Int =
77+
rewrite xs match {
1978
case _: Unit => 0
2079
case _: *:[_, xs1] => _size(erasedValue[xs1]) + 1
2180
}
81+
82+
private[scala] rewrite def _head(xs: Tuple): Any = rewrite xs match {
83+
case _: (x *: _) => erasedValue[x]
84+
}
85+
86+
rewrite def fromArray[T <: Tuple](xs: Array[Object]): T =
87+
rewrite _size(erasedValue[T]) match {
88+
case 0 => ().asInstanceOf[T]
89+
case 1 => Tuple1(xs(0)).asInstanceOf[T]
90+
case 2 => Tuple2(xs(0), xs(1)).asInstanceOf[T]
91+
case 3 => Tuple3(xs(0), xs(1), xs(2)).asInstanceOf[T]
92+
case 4 => Tuple4(xs(0), xs(1), xs(2), xs(3)).asInstanceOf[T]
93+
case 5 => Tuple5(xs(0), xs(1), xs(2), xs(3), xs(4)).asInstanceOf[T]
94+
case 6 => Tuple6(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5)).asInstanceOf[T]
95+
case 7 => Tuple7(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6)).asInstanceOf[T]
96+
case 8 => Tuple8(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7)).asInstanceOf[T]
97+
case 9 => Tuple9(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8)).asInstanceOf[T]
98+
case 10 => Tuple10(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9)).asInstanceOf[T]
99+
case 11 => Tuple11(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10)).asInstanceOf[T]
100+
case 12 => Tuple12(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11)).asInstanceOf[T]
101+
case 13 => Tuple13(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12)).asInstanceOf[T]
102+
case 14 => Tuple14(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13)).asInstanceOf[T]
103+
case 15 => Tuple15(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14)).asInstanceOf[T]
104+
case 16 => Tuple16(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15)).asInstanceOf[T]
105+
case 17 => Tuple17(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16)).asInstanceOf[T]
106+
case 18 => Tuple18(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17)).asInstanceOf[T]
107+
case 19 => Tuple19(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18)).asInstanceOf[T]
108+
case 20 => Tuple20(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18), xs(19)).asInstanceOf[T]
109+
case 21 => Tuple21(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18), xs(19), xs(20)).asInstanceOf[T]
110+
case 22 => Tuple22(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8), xs(9), xs(10), xs(11), xs(12), xs(13), xs(14), xs(15), xs(16), xs(17), xs(18), xs(19), xs(20), xs(21)).asInstanceOf[T]
111+
case _ => TupleXXL(xs).asInstanceOf[T]
112+
}
113+
}
114+
115+
@showAsInfix
116+
sealed class *:[+H, +T <: Tuple] extends Tuple {
117+
import Tuple._
118+
119+
rewrite def head: Any = {
120+
erased val resTpe = Typed(_head(this))
121+
val resVal = rewrite _size(this) match {
122+
case 1 =>
123+
val t = asInstanceOf[Tuple1[_]]
124+
t._1
125+
case 2 =>
126+
val t = asInstanceOf[Tuple2[_, _]]
127+
t._1
128+
case 3 =>
129+
val t = asInstanceOf[Tuple3[_, _, _]]
130+
t._1
131+
case 4 =>
132+
val t = asInstanceOf[Tuple4[_, _, _, _]]
133+
t._1
134+
case n if n > 4 && n <= $MaxSpecialized =>
135+
asInstanceOf[Product].productElement(0)
136+
case n if n > $MaxSpecialized =>
137+
val t = asInstanceOf[TupleXXL]
138+
t.elems(0)
139+
}
140+
resVal.asInstanceOf[resTpe.Type]
141+
}
142+
143+
rewrite def tail: T = ???
144+
22145
}
23146

24147
object *: {
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package scala
2+
3+
package object typelevel {
4+
erased def erasedValue[T]: T = ???
5+
case class Typed[T](val value: T) { type Type = T }
6+
}

library/src/scala/TupleXXL.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package scala
2+
3+
final class TupleXXL private (es: Array[Object]) {
4+
override def toString = elems.mkString("(", ",", ")")
5+
override def hashCode = getClass.hashCode * 41 + elems.deep.hashCode
6+
override def equals(that: Any) = that match {
7+
case that: TupleXXL => this.elems.deep.equals(that.elems.deep)
8+
case _ => false
9+
}
10+
def elems: Array[Object] = es
11+
}
12+
object TupleXXL {
13+
def apply(elems: Array[Object]) = new TupleXXL(elems.clone)
14+
}

tests/run/Tuple.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ object Tuple {
7575
val e4c: Int = conc1(1)
7676
val e5c: Int = conc2(0)
7777
val e6c: Double = conc2(4)
78-
7978
}
8079

8180
object Test extends App

tests/run/tuples1.check

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
()
2+
(1)
3+
(A,1)
4+
(2,A,1)
5+
(B,2,A,1)
6+
(3,B,2,A,1)
7+
(C,3,B,2,A,1)
8+
(4,C,3,B,2,A,1)
9+
(D,4,C,3,B,2,A,1)
10+
h1 = 1
11+
h2 = A
12+
h7 = 4
13+
h8 = D

tests/run/tuples1.scala

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
object Test extends App {
2+
val x0 = (); println(x0)
3+
val x1 = 1 *: x0; println(x1)
4+
val x2 = "A" *: x1; println(x2)
5+
val x3 = 2 *: x2; println(x3)
6+
val x4 = "B" *: x3; println(x4)
7+
val x5 = 3 *: x4; println(x5)
8+
val x6 = "C" *: x5; println(x6)
9+
val x7 = 4 *: x6; println(x7)
10+
val x8 = "D" *: x7; println(x8)
11+
val h1 = x1.head; val h1c: Int = h1; println(s"h1 = $h1")
12+
val h2 = x2.head; val h2c: String = h2; println(s"h2 = $h2")
13+
val h7 = x7.head; val h7c: Int = h7; println(s"h7 = $h7")
14+
val h8 = x8.head; val h8c: String = h8; println(s"h8 = $h8")
15+
/*
16+
val t1 = x1.tail; val t1c: Unit = t1; println(s"t1 = $t1")
17+
val t2 = x2.tail; val t2c: Int *: Unit = t2; println(s"t2 = $t2")
18+
val t7 = x7.tail; val t7c: String *: Int *: Unit = t7.tail.tail.tail.tail; println(s"t7 = $t7")
19+
val t8 = x8.tail; val t8c: Int = t8(6); println(s"t8 = $t8")
20+
val a1_0 = x1(0); val a1_0c: Int = a1_0; println(s"a1_0 = $a1_0")
21+
val a2_0 = x2(0); val a2_0c: String = a2_0; println(s"a2_0 = $a2_0")
22+
val a3_1 = x3(1); val a3_1c: String = a3_1; println(s"a3_1 = $a3_1")
23+
val a4_3 = x4(3); val a4_3c: Int = a4_3; println(s"a4_3 = $a4_3")
24+
val a6_4 = x6(4); val a6_4c: String = a6_4; println(s"a6_4 = $a6_4")
25+
val a8_0 = x8(0); val a8_0c: String = a8_0; println(s"a8_0 = $a8_0")
26+
val c0_0 = x0 ++ x0; val c0_0c: Unit = c0_0; println(s"c0_0 = $c0_0")
27+
val c0_1 = x0 ++ x1; val c0_1c: Int *: Unit = c0_1c; println(s"c0_1 = $c0_1")
28+
val c1_0 = x1 ++ x0; val c1_0c: Int *: Unit = c1_0c; println(s"c1_0 = $c1_0")
29+
val c0_4 = x0 ++ x4; val c0_4c: String *: Int *: String *: Int *: Unit = c0_4; println(s"c0_4 = $c0_4")
30+
val c4_0 = x4 ++ x0; val c4_0c: String *: Int *: String *: Int *: Unit = c4_0; println(s"c4_0 = $c4_0")
31+
val c1_1 = x1 ++ x1; val c1_1c: Int *: Int *: Unit = c1_1; println(s"c1_1 = $c1_1")
32+
val c1_8 = x1 ++ x8; val c1_8c: Int *: String *: Int *: String *: Int *: String *: Int *: String *: Int *: Unit = c1_8; println(s"c1_8 = $c1_8")
33+
val c2_1 = x2 ++ x1; val c2_1c: String *: Int *: Int *: Unit = c2_1; println(s"c2_1 = $c2_1")
34+
val c2_2 = x2 ++ x2; val c2_2c: String *: Int *: String *: Int *: Unit = c2_2; println(s"c2_2 = $c2_2")
35+
val c2_3 = x2 ++ x3; val c2_3c: String *: Int *: Int *: String *: Int *: Unit = c2_3; println(s"c2_3 = $c2_3")
36+
val c3_3 = x3 ++ x3; val c3_3c: Int *: String *: Int *: Int *: String *: Int *: Unit = c3_3; println(s"c3_3 = $c3_3")*/
37+
}

0 commit comments

Comments
 (0)