I am trying to get my head around covariance in respect with methods creating new immutable types using lower bounds
class ImmutableArray[+T](item: T, existing:
It works because the append method returns a broader class than the original one. Let's conduct a little experiment.
scala> case class myIntClass(a:Int)
defined class myIntClass
scala> case class myIntPlusClass(a:Int, b:Int)
defined class myIntPlusClass
scala> class ImmutableArray[+T](item: T, existing: List[T] = Nil){
|
| private val items = item :: existing
|
| def append[S >: T](value: S) = new ImmutableArray[S](value,items)
| def getItems = items
| }
defined class ImmutableArray
scala> val ia = new ImmutableArray[myIntClass](myIntClass(3))
ia: ImmutableArray[myIntClass] = ImmutableArray@5aa91edb
scala> ia.getItems
res15: List[myIntClass] = List(myIntClass(3))
scala> ia.append(myIntPlusClass(3,5))
res16: ImmutableArray[Product with Serializable] = ImmutableArray@4a35a157
scala> res16.getItems
res17: List[Product with Serializable] = List(myIntPlusClass(3,5), myIntClass(3))
scala> res16
res18: ImmutableArray[Product with Serializable] = ImmutableArray@4a35a157
So you can add a derived class here, but it only works due to the fact that the base type of the resulting array is demoted to a lowest common denominator (in this case, Serializable).
If we try to force the derived type on the resulting array, it won't work:
scala> ia.append[myIntPlusClass](myIntPlusClass(3,5))
:23: error: type arguments [myIntPlusClass] do not conform to method append's type parameter bounds [S >: myIntClass]
ia.append[myIntPlusClass](myIntPlusClass(3,5))
Trying to do the same making append return an array of derived types won't work, because T is not a subclass of S:
scala> class ImmutableArray[+T](item: T, existing: List[T] = Nil){
|
| private val items = item :: existing
|
| def append[S <: T](value: S) = new ImmutableArray[S](value,items)
| def getItems = items
| }
:21: error: type mismatch;
found : List[T]
required: List[S]
def append[S <: T](value: S) = new ImmutableArray[S](value,items)