From List[+T]
I understand a list of dogs is also a list of animals which aligns perfectly with the intuition. From def :: [B >: A](elem: B): List[B]
I understand I can add an animal (B
, less specific) to a list of dogs (A
, more specific) and will get back a list of animals. This aligns with the intuition as well. So basically List
is good.
From Array[T]
I understand an array of dogs is not (could not be used in place of a) an array of animals which is rather counterintuitive. An array of dogs is indeed an array of animals as well but obviously Scala disagrees.
I was hoping someone intuitively explain why Array
in invariant, preferably in terms of dogs (or cats).
There is Why are Arrays invariant, but Lists covariant? but I'm looking for a more intuitive explanation that doesn't (heavily) involve the type system.
Related to Why is Scala's immutable Set not covariant in its type?
The reason is pretty simple. Is because
Array
is a mutable collection. Remember there is a very easy rule of thumb about variance.If it produces something it can be covariant.
If it consumes something it can be contravariant.
That is why
Functions
are contravariant on input and covariant on output.Because
Arrays
are mutable they are in fact both producers and consumers of something, so they have to be invariant.Let me show why it has to be like that with a simple example.
You can reproduce this error in Java using normal
Arrays
, Scala will simply not let you compile.