Reputation: 306
In Scala, why does setting lower type bounds on a method type parameter not enforce the "is a super-type" restriction on the method arguements ?
object TypeBounds extends App {
class MotorVehicle
class Truck extends MotorVehicle
class Car extends MotorVehicle
class Saloon extends Car
class HatchBackSaloon extends Saloon
def lowerTypeBound[C >: Car](c: C): C = c
def upperTypeBound[C <: Car](c: C): C = c
// Works. HatchBackSaloon is a sub class of Car
println(upperTypeBound(new HatchBackSaloon()))
// as expected doesn't compile. Truck is not a subclass of Car
println(upperTypeBound( new Truck()))
// Compiles and runs, but why ? HatchBackSaloon is not a super class of Car.
println(lowerTypeBound(new HatchBackSaloon()))
}
Upvotes: 3
Views: 69
Reputation: 40500
C
in your example is materialized as Car
, not HatchbackSaloon
.
A function looking like def lowerTypeBound(c: Car): Car
can accept arguments of type HatchbackSaloon
, it is not surprising, right?
Try something like this:
val result: HatchBackSaloon = lowerTypeBound(new HatchBackSaloon)
This will not compile, because it would require C
to be HatchbackSaloon
, which is not a superclass of Car
. But this will work:
val result: MotorVehicle = lowerTypeBound(new HatchbackSaloon)
because C
is MotorVehicle
here, and that is allowed.
Upvotes: 6