私は scala の型システムをいじっていて、奇妙なケースを見つけました。私には、共変と共分散を理解していないと信じる強い理由があります。
これは私の問題ケースです:
Point と、Point のサブクラスである ColorPoint という 2 つのクラスがあります。
class Point(val x : Int, val y : Int)
class ColorPoint(x : Int, y : Int, val red : Int, val green : Int, val blue : Int) extends Point(x,y)
このクラスは B を A にキャストしますが、B は A のスーパータイプである必要があります。
class CoVariance[+A]{
def cast[B >: A](x : B) : A = {
return x.asInstanceOf[A]
}
}
このクラスは B を A にキャストしますが、B は A のスーパータイプである必要があります。
class ContraVariance[-A]{
def cast[B, A <: B](x : B) : A = {
return x.asInstanceOf[A]
}
}
ケース 1:
val co = new CoVariance[Point]
val color_point = new ColorPoint(1,2,3,4,5)
val point_co = co.cast(color_point)
println(point_co.x)
これを書き出すと:
// Covariance[Point] ->
// cast[B :> Point](x : B) : Point -> (fill in ColorPoint)
// Cast[ColorPoint :> Point] : Point
ColorPoint は Point のスーパータイプではないため、これは間違っていると思いますが、scala は文句を言いません。
次の:
val contra = new ContraVariance[Point]
val color_point_contra = new ColorPoint(1,2,3,4,5)
val point_contra = contra.cast(color_point_contra)
println(point_contra.x)
これを書き出すと:
// ContraVariance[Point] ->
// cast[B, Point <: B](x : B) : Point -> (fill in ColorPoint)
// cast[ColorPoint, Point <: ColorPoint] : Point
これも間違っていると思いますが、scala は文句を言いません。Point は ColorPoint のサブタイプではないと思います。
私の推論は正しいですか、それとも何かが欠けていますか?