Skip to content

Commit 6ec3054

Browse files
committed
Add generative operations to tuples
1 parent 6445f85 commit 6ec3054

File tree

5 files changed

+161
-10
lines changed

5 files changed

+161
-10
lines changed

library/src-scala3/scala/Tuple.scala

Lines changed: 104 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,119 @@
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 if n > $MaxSpecialized =>
25+
println(n)
26+
asInstanceOf[TupleXXL].elems
27+
}
328

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

8-
import typelevel._
51+
object Tuple {
52+
transparent val $MaxSpecialized = 22
53+
54+
val $emptyArray = Array[Object]()
55+
56+
def $toArray(xs: Tuple, n: Int) = {
57+
val arr = new Array[Object](n)
58+
var i = 0
59+
var it = xs.asInstanceOf[Product].productIterator
60+
while (i < n) {
61+
arr(i) = it.next().asInstanceOf[Object]
62+
i += 1
63+
}
64+
arr
65+
}
66+
67+
def $consArray[H](x: H, elems: Array[Object]): Array[Object] = {
68+
val elems1 = new Array[Object](elems.length + 1)
69+
elems1(0) = x.asInstanceOf[Object]
70+
Array.copy(elems, 0, elems1, 1, elems.length)
71+
elems1
72+
}
73+
74+
private rewrite def _pair[H, T <: Tuple] (x: H, xs: T): Tuple =
75+
erasedValue[H *: T]
976

10-
sealed trait Tuple extends Any
77+
private rewrite def _size(xs: Tuple): Int =
78+
rewrite xs match {
79+
case _: Unit => 0
80+
case _: *:[_, xs1] => _size(erasedValue[xs1]) + 1
81+
}
82+
83+
rewrite def fromArray[T <: Tuple](xs: Array[Object]): T =
84+
rewrite _size(erasedValue[T]) match {
85+
case 0 => ().asInstanceOf[T]
86+
case 1 => Tuple1(xs(0)).asInstanceOf[T]
87+
case 2 => Tuple2(xs(0), xs(1)).asInstanceOf[T]
88+
case 3 => Tuple3(xs(0), xs(1), xs(2)).asInstanceOf[T]
89+
case 4 => Tuple4(xs(0), xs(1), xs(2), xs(3)).asInstanceOf[T]
90+
case 5 => Tuple5(xs(0), xs(1), xs(2), xs(3), xs(4)).asInstanceOf[T]
91+
case 6 => Tuple6(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5)).asInstanceOf[T]
92+
case 7 => Tuple7(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6)).asInstanceOf[T]
93+
case 8 => Tuple8(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7)).asInstanceOf[T]
94+
case 9 => Tuple9(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8)).asInstanceOf[T]
95+
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]
96+
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]
97+
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]
98+
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]
99+
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]
100+
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]
101+
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]
102+
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]
103+
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]
104+
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]
105+
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]
106+
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]
107+
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]
108+
case _ => TupleXXL(xs).asInstanceOf[T]
109+
}
110+
}
11111

12112
@showAsInfix
13113
sealed class *:[+H, +T <: Tuple] extends Tuple {
14114
rewrite def head: H = ???
15115
rewrite def tail: T = ???
16116

17-
rewrite private def _size(xs: Tuple): Int = //rewrite
18-
xs match {
19-
case _: Unit => 0
20-
case _: *:[_, xs1] => _size(erasedValue[xs1]) + 1
21-
}
22117
}
23118

24119
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.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+
/*
12+
val h1 = x1.head; val h1c: Int = h1; println(s"h1 = $h1")
13+
val h2 = x2.head; val h2c: String = h2; println(s"h2 = $h2")
14+
val h7 = x7.head; val h7c: Int = h7; println(s"h7 = $h7")
15+
val h8 = x8.head; val h8c: String = h8; println(s"h8 = $h8")
16+
val t1 = x1.tail; val t1c: Empty = t1; println(s"t1 = $t1")
17+
val t2 = x2.tail; val t2c: Int *: Empty = t2; println(s"t2 = $t2")
18+
val t7 = x7.tail; val t7c: String *: Int *: Empty = 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: Empty = c0_0; println(s"c0_0 = $c0_0")
27+
val c0_1 = x0 ++ x1; val c0_1c: Int *: Empty = c0_1c; println(s"c0_1 = $c0_1")
28+
val c1_0 = x1 ++ x0; val c1_0c: Int *: Empty = c1_0c; println(s"c1_0 = $c1_0")
29+
val c0_4 = x0 ++ x4; val c0_4c: String *: Int *: String *: Int *: Empty = c0_4; println(s"c0_4 = $c0_4")
30+
val c4_0 = x4 ++ x0; val c4_0c: String *: Int *: String *: Int *: Empty = c4_0; println(s"c4_0 = $c4_0")
31+
val c1_1 = x1 ++ x1; val c1_1c: Int *: Int *: Empty = 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 *: Empty = c1_8; println(s"c1_8 = $c1_8")
33+
val c2_1 = x2 ++ x1; val c2_1c: String *: Int *: Int *: Empty = c2_1; println(s"c2_1 = $c2_1")
34+
val c2_2 = x2 ++ x2; val c2_2c: String *: Int *: String *: Int *: Empty = c2_2; println(s"c2_2 = $c2_2")
35+
val c2_3 = x2 ++ x3; val c2_3c: String *: Int *: Int *: String *: Int *: Empty = c2_3; println(s"c2_3 = $c2_3")
36+
val c3_3 = x3 ++ x3; val c3_3c: Int *: String *: Int *: Int *: String *: Int *: Empty = c3_3; println(s"c3_3 = $c3_3")*/
37+
}

0 commit comments

Comments
 (0)