Here _ is just an unnamed type of type, no more, no less. There is no difference between def foo[_ <: Bar] = 3 and def foo[X <: Bar] = 3 , where X not used.
UPDATE
In response to: "I cannot come up with a usage example for an unused type, I would be grateful for it":
Note that this is almost the same as asking what is the purpose of having an argument if it is not used, for example:
def foo( x: Int ) = 123
Usually a good reason for this is that the method conforms to the form expected in some other API. For example, you want to pass a method (or rather its eta-expansio) to another method that expects a parameter. Example:
scala> List(1,2,3).map(foo) res0: List[Int] = List(123, 123, 123)
Another possibility is that your method is an override:
trait A { def foo( x: Int ): Int } trait B extends A { def foo( x: Int ) = 123 }
The same rational applies to type parameters. For example, for the main case:
trait A { def foo[X <: Bar]: Int } trait B extends A { def foo[_<:Bar] = 3 }
B.foo does not need a type parameter to implement it, but it must be there (albeit anonymous) to match the method that it overrides.
source share