Иногда у Scala возникают проблемы с выбором типов. Цель здесь - понять, почему и попытаться помочь Scala сделать лучший вывод.Как помочь Scala в выводе типа?
Проблема лучше объяснить на простом примере:
trait A
trait B
class G[Ao <: A, Bo <: B](a: Ao, b: Bo)
// This is my "complex" class with 3 type parameters
class X[Ao <: A, Bo <: B, Go <: G[Ao,Bo]](a: Ao, b: Bo, g: Go)
val a = new A{}
val b = new B{}
val g = new G(a,b)
Здесь тип ОО ниже является совершенно Inferred:
class OO extends X(a,b,g) // Type of X[A,B,G[A,B]]
Однако, если мы изменим один из аргументов быть опцией (или любой коллекцией, которая есть), и мы предоставляем пустую коллекцию (или None), после чего вывод не работает.
case class X[Ao <: A, Bo <: B, Go <: G[Ao,Bo]](a: Ao, b: List[Bo], g: Go)
class OO extends X(a,List(),g)
<console>:XX: error: inferred type arguments [A,Nothing,G[A,B]] do not conform to class X's type parameter bounds [Ao <: A,Bo <: B,Go <: G[Ao,Bo]]
class OO extends X(a,List(),g)
^
<console>:XX: error: type mismatch;
found : A
required: Ao
class OO extends X(a,List(),g)
^
<console>:XX: error: type mismatch;
found : G[A,B]
required: Go
class OO extends X(a,List(),g)
Это может быть исправлено путем явной передачи всех параметров OO, как это:
class OO extends X[A,B,G[A,B]](a,List(),g)
Дело в том, G уже имеет свои виды, и из определения X, мы видим, что G принимает первые два параметра X, поэтому, если мы знаем G, у нас есть все необходимое, чтобы вывести параметры X. Могу ли я сделать что-то другое, чтобы помочь Scala с выводом? У меня есть класс, который имеет гораздо больше параметров, чем X, и теперь я всегда должен их явно определять. Я пытаюсь понять, есть ли что-то, что я могу сделать, чтобы помочь Scala успешно вывести типы.
Это выглядит многообещающе! Позвольте мне проверить это, и я вернусь к вам. – marios
Можете ли вы немного рассказать о своих рассуждениях? Что заставило вас думать о высших единомышленниках? – marios
Я добавил (вроде) объяснение ответа. Я думаю, что кто-то более опытный с типами систем и функциональным программированием мог бы объяснить, почему он работает лучше меня. Я знаю только по опыту, что компилятор не может вывести параметры типа в этих случаях, и вам нужно «помочь», указав границы, как я. Извините, я не мог больше помочь :) –