Во-первых, нет, этот код не компилируется: это ошибки компиляции, а не исключения времени выполнения.Вы можете видеть, потому что он начинается с Error:
, указывает на точную позицию в исходном коде (исключения имеют только номер строки), и нет трассировки стека.
Теперь, если он скомпилирован, он не будетэто не работает, но это отдельная проблема.
Так почему же он не компилируется?Тип weights.zip(points).map(...)
равен Seq[Seq[Double]]
, поэтому подпись reduce
становится reduce[A1 >: Seq[Double]](op: (A1, A1) => A1): A1
.Обратите внимание, что типы возврата и аргумента аргумента reduce
должны совпадать, а в вашем случае они не совпадают (у вас есть (Seq[Double], Seq[Double]) => Seq[T]
).Само по себе этого не достаточно для компиляции.
Ожидаемый тип всего weights.zip(points).map(...).reduce(...)
равен Seq[T]
, поэтому компилятору нужно выбрать A1
, то есть:
супертип Seq[Double]
для удовлетворения ограничения
подтип Seq[T]
для соответствия типов возвращаемых данных
Такиетип не существует (без дополнительных ограничений на T
), но если он это сделает, это будет Seq[SomeType]
, и это все, что должен получить компилятор.Почему в конечном итоге отображается Any
, я действительно не вижу.
Как добиться этого преобразования из Seq [Double] в Seq [T]?
Это имеет больше смысла, если у вас есть weights: Seq[T], points: Seq[Seq[T]]
.В этом случае используйте Numeric
.Существует довольно много ответов о переполнении стека и за его пределами, объясняющих, как, например, Scala-эквивалент числа Java .
Для weights: Seq[Double], points: Seq[Seq[Double]]
я бы просто добавил функцию Double => T
в качестве дополнительного аргумента:
def linearInterpolation(weights: Seq[Double], points: Seq[Seq[Double]])(fromDouble: Double => T) : Seq[T] = {
weights.zip(points).map(
weight_point => weight_point._2.map(coordinate => weight_point._1 * coordinate)
).reduce((point_a : Seq[Double], point_b : Seq[Double]) => point_a.zip(point_b).map(coordinate_points => coordinate_points._1 + coordinate_points._2)).map(fromDouble)
}