diff options
author | Martin Odersky <odersky@gmail.com> | 2017-01-31 14:46:24 +1100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2017-02-08 19:35:58 +1100 |
commit | fe09e0d8fe68e0b48d5e864e1de12ae5ee86077d (patch) | |
tree | 67279b95ae5e7a2f2ebd2418d3a4b12002f107ae /tests/run/generic/List.scala | |
parent | bc06d17ebfd7c8d6003dffe925c3cf9ebca6b1b9 (diff) | |
download | dotty-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.scala | 89 |
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 |