aboutsummaryrefslogtreecommitdiff
path: root/tests/run/generic/Tree.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/Tree.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/Tree.scala')
-rw-r--r--tests/run/generic/Tree.scala113
1 files changed, 113 insertions, 0 deletions
diff --git a/tests/run/generic/Tree.scala b/tests/run/generic/Tree.scala
new file mode 100644
index 000000000..f4e706944
--- /dev/null
+++ b/tests/run/generic/Tree.scala
@@ -0,0 +1,113 @@
+package generic
+
+import Shapes._
+
+/** enum Tree[TS] {
+ * case True extends Tree[Boolean]
+ * case False extends Tree[Boolean]
+ * case Zero extends Tree[Int]
+ * case Succ(n: Tree[Int]) extends Tree[Int]
+ * case Pred(n: Tree[Int]) extends Tree[Int]
+ * case IsZero(n: Tree[Int]) extends Tree[Boolean]
+ * case If(cond: Boolean, thenp: Tree[T], elsep: Tree[T]) extends Tree[T]
+ * }
+ */
+sealed trait Tree[TR] extends Enum
+
+object Tree {
+
+ val True: Tree[Boolean] = new Tree[Boolean] {
+ def enumTag = 0
+ override def toString = "True"
+ }
+ implicit def TrueSingleton: Singleton[True.type] = new Singleton[True.type](True)
+
+ val False: Tree[Boolean] = new Tree[Boolean] {
+ def enumTag = 1
+ override def toString = "False"
+ }
+ implicit def FalseSingleton: Singleton[False.type] = new Singleton[False.type](False)
+
+ val Zero: Tree[Int] = new Tree[Int] {
+ def enumTag = 2
+ override def toString = "Zero"
+ }
+ implicit def ZeroSingleton: Singleton[Zero.type] = new Singleton[Zero.type](Zero)
+
+ abstract case class Succ(n: Tree[Int]) extends Tree[Int] {
+ def enumTag = 3
+ }
+ object Succ {
+ def apply(x: Tree[Int]): Tree[Int] = new Succ(x) {}
+ implicit def SuccShape: Succ `shaped` Tree[Int] = new (Succ `shaped` Tree[Int]) {
+ def toShape(x: Succ) = x.n
+ def fromShape(x: Tree[Int]) = new Succ(x) {}
+ }
+ }
+
+ abstract case class Pred(n: Tree[Int]) extends Tree[Int] {
+ def enumTag = 4
+ }
+ object Pred {
+ def apply(x: Tree[Int]): Tree[Int] = new Pred(x) {}
+ implicit def PredShape: Pred `shaped` Tree[Int] = new (Pred `shaped` Tree[Int]) {
+ def toShape(x: Pred) = x.n
+ def fromShape(x: Tree[Int]) = new Pred(x) {}
+ }
+ }
+
+ abstract case class IsZero(n: Tree[Int]) extends Tree[Boolean] {
+ def enumTag = 5
+ }
+ object IsZero {
+ def apply(x: Tree[Int]): Tree[Boolean] = new IsZero(x) {}
+ implicit def IsZeroShape: IsZero `shaped` Tree[Int] = new (IsZero `shaped` Tree[Int]) {
+ def toShape(x: IsZero) = x.n
+ def fromShape(x: Tree[Int]) = new IsZero(x) {}
+ }
+ }
+
+ abstract case class If[T](cond: Tree[Boolean], thenp: Tree[T], elsep: Tree[T]) extends Tree[T] {
+ def enumTag = 6
+ }
+ object If {
+ def apply[T](cond: Tree[Boolean], thenp: Tree[T], elsep: Tree[T]): Tree[T] = new If(cond, thenp, elsep) {}
+ type Shape[T] = Prod[Tree[Boolean], Prod[Tree[T], Tree[T]]]
+ implicit def IfShape[T]: If[T] `shaped` Shape[T] =
+ new (If[T] `shaped` Shape[T]) {
+ def toShape(x: If[T]) = Prod(x.cond, Prod(x.thenp, x.elsep))
+ def fromShape(x: Shape[T]) = new If(x.fst, x.snd.fst, x.snd.snd) {}
+ }
+ }
+
+ type Shape[T] =
+ Sum[
+ Sum[
+ Sum[True.type, False.type],
+ Sum[Zero.type, Succ]],
+ Sum[
+ Sum[Pred, IsZero],
+ If[T]]]
+
+ implicit def TreeShape[TS]: Tree[TS] `unfolds` Shape[TS]
+ = new (Tree[TS] `shaped` Shape[TS]) {
+ def toShape(x: Tree[TS]) = x match {
+ case True => Fst(Fst(Fst(True)))
+ case False => Fst(Fst(Snd(False)))
+ case Zero => Fst(Snd(Fst(Zero)))
+ case x: Succ => Fst(Snd(Snd(x)))
+ case x: Pred => Snd(Fst(Fst(x)))
+ case x: IsZero => Snd(Fst(Snd(x)))
+ case x: If[TS] => Snd(Snd(x))
+ }
+ def fromShape(x: Shape[TS]): Tree[TS] = x match {
+ case Fst(Fst(Fst(_true))) => _true.asInstanceOf[Tree[TS]]
+ case Fst(Fst(Snd(_false))) => _false.asInstanceOf[Tree[TS]]
+ case Fst(Snd(Fst(zero))) => zero.asInstanceOf[Tree[TS]]
+ case Fst(Snd(Snd(succ))) => succ.asInstanceOf[Tree[TS]]
+ case Snd(Fst(Fst(pred))) => pred.asInstanceOf[Tree[TS]]
+ case Snd(Fst(Snd(isZero))) => isZero.asInstanceOf[Tree[TS]]
+ case Snd(Snd(_if)) => _if
+ }
+ }
+} \ No newline at end of file