Проблема, которую вы наблюдаете, сводится к тому, что Array
в Scala * инвариант .Например:
trait Base
class Derived extends Base
val bases: Array[Base] = Array[Derived](new Derived)
Сообщение об ошибке, сгенерированное этим кодом, немного яснее:
type mismatch;
found : Array[Derived]
required: Array[Base]
Note: Derived <: Base, but class Array is invariant in type T.
Более подробную информацию о дисперсии можно найти, например, здесь .По сути, идея заключается в том, что если некоторый тип Collection[T]
инвариантен в аргументе типа T
, это означает, что вы не можете присвоить значение типа Collection[Derived]
переменной / параметру ожидаемого типа.Collection[Base]
, и наоборот.
Есть очень веские причины для инвариантности массивов: массив является изменяемым, и если он не был инвариантным и, например, ковариантным, то можно было бы нарушитьгарантии ввода:
trait Base
class Derived1 extends Base
class Derived2 extends Base
val derived1s: Array[Derived1] = Array(new Derived1)
val bases: Array[Base] = derived1s
bases(0) = new Derived2 // putting Derived2 in an array of Derived1
val derived1: Derived1 = derived1s(0) // type mismatch
Естественно, для конструкторов «вложенных» типов инвариантность распространяется, поэтому вы не можете присвоить Array[Array[Equation]]
1024 *.
Самый простой способ исправить эточтобы использовать некоторую ковариантную коллекцию (которая обязательно неизменна):
class Equation(eq: Vector[Vector[Value]]) extends Value {
...
}
Vector[T]
, будучи неизменной коллекцией, является ковариантным в своем аргументе типа, поэтому можно назначить Vector[Derived]
до Vector[Base]
.Поэтому ваш код будет работать.