Question

I'm trying to understand Scala's existential types.

Is there any difference between:

def foo[X <: Bar] = 3

and

def foo[_ <: Bar] = 3

or are they something more than just unnamed type parameters?

Was it helpful?

Solution

Here _ is indeed just an unnamed type parameter, no more, no less. There is no difference between def foo[_ <: Bar] = 3 and def foo[X <: Bar] = 3 where X is unused.

UPDATE:

In response to: "I can't think of a use case for an unused type, I'd be grateful for one":

Note that this is pretty much the same as asking what is the purpose of having an argument if it is not used, such as in:

def foo( x: Int ) = 123

Usually a good reason for this is that the method conforms to a shape that is expected in some other API. By example, you want to pass the method (or rather its eta-expansio) to a another method that expects a parameter. By 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 for type parameters. By example for the overriding case:

trait A {
  def foo[X <: Bar]: Int
}

trait B extends A {
  def foo[_<:Bar] = 3
}

B.foo does not need the type parameter in its implementation, but it has to be there (though unnamed) to conform to the method it is overriding.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top