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()))
}
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.
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