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?
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.
© 2022 - 2024 — McMap. All rights reserved.
List[_]
is an existential type, butdef foo[_]
just defines a generic method with an unnamed type parameter. Yes, both feature an underscore, but for two entirely different things. – Tatia