aboutsummaryrefslogtreecommitdiff
path: root/tests/run/lazy-implicit-nums.scala
diff options
context:
space:
mode:
Diffstat (limited to 'tests/run/lazy-implicit-nums.scala')
-rw-r--r--tests/run/lazy-implicit-nums.scala58
1 files changed, 58 insertions, 0 deletions
diff --git a/tests/run/lazy-implicit-nums.scala b/tests/run/lazy-implicit-nums.scala
new file mode 100644
index 000000000..967472735
--- /dev/null
+++ b/tests/run/lazy-implicit-nums.scala
@@ -0,0 +1,58 @@
+trait Nat
+case class S(x: Nat) extends Nat
+case class Z() extends Nat
+
+trait Sum[+S1, +S2]
+case class Fst[+F](x: F) extends Sum[F, Nothing]
+case class Snd[+S](x: S) extends Sum[Nothing, S]
+
+trait shaped[SH1, SH2] {
+ def toShape(x: SH1): SH2
+ def fromShape(x: SH2): SH1
+}
+
+object Test {
+
+ type NatShape = Sum[Nat, Z]
+
+ implicit def natShape: Nat `shaped` NatShape =
+ new (Nat `shaped` NatShape) {
+ def toShape(n: Nat) = n match {
+ case S(m) => Fst(m)
+ case Z() => Snd(Z())
+ }
+ def fromShape(s: NatShape) = s match {
+ case Fst(n) => S(n)
+ case Snd(_) => Z()
+ }
+ }
+
+ trait Countable[T] {
+ def count(x: T): Int
+ }
+
+ implicit def ShapedCountable[T, U](implicit
+ ev1: T shaped U,
+ ev2: Countable[U]
+ ): Countable[T] =
+ new Countable[T] {
+ def count(x: T) = ev2.count(ev1.toShape(x))
+ }
+
+ implicit def SumCountable[T, U](implicit
+ ev1: => Countable[T]
+ ): Countable[Sum[T, U]] =
+ new Countable[Sum[T, U]] {
+ def count(s: Sum[T, U]) = s match {
+ case Fst(x) => ev1.count(x) + 1
+ case Snd(_) => 0
+ }
+ }
+
+ def count[T, U >: T](x: T)(implicit ev1: Countable[U]) = ev1.count(x)
+
+ def main(args: Array[String]) = {
+ println(
+ count(S(S(S(Z())))))
+ }
+}