Tuesday, May 1, 2012

Variance and bounds example

class A
class B extends A
class C extends B
class D extends C

class E

class X[+T] {                        // T covariant for input types
  def add[U >: T](x: U): X[U] = this // U contravariant for return type
}

class Y[+T <: A] {                   // This time with an upper bound A
  def add[U >: T <: A](y: U): Y[U] = this
}

val a = new A
val b = new B
val c = new C
val d = new D

val x = new X[C]
val x2 = x.add(b)    // x2 type becomes X[B]
val x3 = x.add(d)    // x3 remains of type X[C]
val x4 = x.add(10)   // x4 type becomes X[Any]
val x6 = x.add("Z")  // x5 type becomes X[java.lang.Object]

val y = new Y[C]
val y2 = y.add(b)    // y2 type becomes X[B]
val y3 = y.add(d)    // y3 remains of type X[C]
//val y4 = y.add(2)  // Won't compile as Y has an upper bound, it must inherits from A


class Z {
  def add[T<%E](e:T) = this  // View Bound, it exists an implicit conversion to E
}
val z  = new Z
//val z1 = z.add(a)  // Won't compile as there no implicit conversion from A to E
implicit def a2E(a:A) = new E
val z2 = z.add(a)

No comments:

Post a Comment