confusion in understanding scala's bound

generics, scala

Solution

The important thing to remember here is that `Any` is a super type of any type, i.e.

Any >: A

In particular, assume

val t = new Test[Int]

This is, `A` is `Int`. Now we call

t.test("foo")

`"foo"` is of type `String`, but string is subtype of `Any`, and hence can be considered as such, therefore `test[B >: A](b : B)` can be called with `b` being `"foo"` and `B` being `Any`.

The following example should illustrate this, consider

class Test[+A](a : A) {
  def test[B >: A](b : B) : (A,B) = (a,b)
}

now, using

val t = new Test(3)
val x = t.test("foo")

we get

x: (Int, Any) = (3,foo)

Finally, to add some details, Scala will not always pick `Any`, but the least common supertype of `A` and `B`. This happens to be `Any` for `Int` and `String` (see http://www.scala-lang.org/old/node/128 ), but may be something different for other examples, e.g., for

val s = new Test(Nil)
val y = s.test("foo")
val z = s.test(List(1))

we will get

y: (scala.collection.immutable.Nil.type, java.io.Serializable) = (List(),foo)
z: (scala.collection.immutable.Nil.type, List[Int]) = (List(),List(1))

Also note that the lower bound does not prevent passing subtypes of `A`

scala> val a = new Test(new AnyRef())
a: Test[java.lang.Object] = Test@6771a12

scala> a.test("foo")
res6: (java.lang.Object, java.lang.Object) = (java.lang.Object@78b99f12,foo)

So, the question is, what are lower type bounds useful for? One possible answer is that they can be used for "controlling" the types of "output" positions, as typically used for covariant type parameters, see, e.g., http://docs.scala-lang.org/tutorials/tour/lower-type-bounds.html Roughly speaking, when appending an element to a (covariant) list of type `A`, you want to make sure that the resulting list is "at least" of type `A`. (I'm sorry for this being in parts hand-wavey, but as it goes beyond the scope of the original question, I just wanted to give a brief idea of why they are needed, for a full answer, it's probably better to create a new question)

Problem

I am reading Demystifying Scala Type System , in the 17th slide there is a snippet: ``` class Test[+A] { def test[B >: A](b: B): String = b.toString } ``` The slide says method test will accept type A or any super type of A. But seems I could pass any type to test. ``` vat t = new Test[Int] t.test("foo") t.test(List(1, 2, 3)) ``` I have the same confusion when I read Programming in Scala .

Original source