aboutsummaryrefslogtreecommitdiff
path: root/tests/run/generic/List.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-01-31 14:46:24 +1100
committerMartin Odersky <odersky@gmail.com>2017-02-08 19:35:58 +1100
commitfe09e0d8fe68e0b48d5e864e1de12ae5ee86077d (patch)
tree67279b95ae5e7a2f2ebd2418d3a4b12002f107ae /tests/run/generic/List.scala
parentbc06d17ebfd7c8d6003dffe925c3cf9ebca6b1b9 (diff)
downloaddotty-fe09e0d8fe68e0b48d5e864e1de12ae5ee86077d.tar.gz
dotty-fe09e0d8fe68e0b48d5e864e1de12ae5ee86077d.tar.bz2
dotty-fe09e0d8fe68e0b48d5e864e1de12ae5ee86077d.zip
ADT and Serialization test
The test exercises all the improvements made in previous commits of this branch.
Diffstat (limited to 'tests/run/generic/List.scala')
-rw-r--r--tests/run/generic/List.scala89
1 files changed, 89 insertions, 0 deletions
diff --git a/tests/run/generic/List.scala b/tests/run/generic/List.scala
new file mode 100644
index 000000000..3f3657656
--- /dev/null
+++ b/tests/run/generic/List.scala
@@ -0,0 +1,89 @@
+package generic
+
+import Shapes._
+
+/** enum List[T] {
+ * case Cons(x: T, xs: List[T])
+ * case Nil()
+ * }
+ */
+sealed trait List0[T] extends Enum
+object List0 {
+ abstract case class Cons[T](hd: T, tl: List0[T]) extends List0[T] {
+ def enumTag = 0
+ }
+ object Cons {
+ def apply[T](x: T, xs: List0[T]): List0[T] = new Cons(x, xs) {}
+ implicit def ConsShape[T]: Cons[T] `shaped` Prod[T, List0[T]] =
+ new (Cons[T] `shaped` Prod[T, List0[T]]) {
+ def toShape(x: Cons[T]) = Prod(x.hd, x.tl)
+ def fromShape(p: Prod[T, List0[T]]) = new Cons(p.fst, p.snd) {}
+ }
+ }
+
+ abstract case class Nil[T]() extends List0[T] {
+ def enumTag = 1
+ }
+ object Nil {
+ def apply[T](): List0[T] = new Nil[T]() {}
+ implicit def NilShape[T]: Nil[T] `shaped` Unit =
+ new (Nil[T] `shaped` Unit) {
+ def toShape(x: Nil[T]) = ()
+ def fromShape(x: Unit) = new Nil[T]() {}
+ }
+ }
+
+ implicit def List0Shape[T]: List0[T] `shaped` Sum[Cons[T], Nil[T]] =
+ new (List0[T] `shaped` Sum[Cons[T], Nil[T]]) {
+ def toShape(x: List0[T]) = x match {
+ case x: Cons[T] => Fst(x)
+ case x: Nil[T] => Snd(x)
+ }
+ def fromShape(x: Sum[Cons[T], Nil[T]]) = x match {
+ case Fst(c) => c
+ case Snd(n) => n
+ }
+ }
+}
+
+/** enum List[T] {
+ * case Cons(x: T, xs: List[T])
+ * case Nil extends List[Nothing]
+ * }
+ */
+sealed trait List[+T] extends Enum
+object List {
+ abstract case class Cons[T](hd: T, tl: List[T]) extends List[T] {
+ def enumTag = 0
+ }
+ object Cons {
+ def apply[T](x: T, xs: List[T]): List[T] = new Cons(x, xs) {}
+ type Shape[T] = Prod[T, List[T]]
+ implicit def ConsShape[T]: Cons[T] `shaped` Shape[T] =
+ new (Cons[T] `shaped` Shape[T]) {
+ def toShape(x: Cons[T]) = Prod(x.hd, x.tl)
+ def fromShape(p: Shape[T]) = new Cons(p.fst, p.snd) {}
+ }
+ }
+
+ val Nil = new List[Nothing] {
+ def enumTag = 1
+ override def toString = "Nil"
+ }
+
+ implicit def NilSingleton: Singleton[Nil.type] = new Singleton[Nil.type](Nil)
+
+ type Shape[T] = Sum[Cons[T], Nil.type]
+
+ implicit def ListShape[T]: List[T] `unfolds` Shape[T] =
+ new (List[T] `shaped` Shape[T]) {
+ def toShape(x: List[T]) = x match {
+ case x: Cons[T] => Fst(x)
+ case Nil => Snd(Nil)
+ }
+ def fromShape(x: Shape[T]): List[T] = x match {
+ case Fst(c) => c
+ case Snd(n) => n
+ }
+ }
+} \ No newline at end of file