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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With