Как скомпилировать код с имплицитными и экзистенциальными типами с помощью 2.13
upd У меня есть функция, которая принимает типы с экзистенциальными данными:
trait QueryValue[V]
trait QueryValueFormats {
implicit object IntQueryValue extends QueryValue[Int]
implicit object StringQueryValue extends QueryValue[String]
}
trait Magnets {
trait NumericCol[C]
implicit def numericFromInt[T <: Int](s: T)(implicit evidence: QueryValue[T]): NumericCol[T] = new NumericCol[T] {}
implicit def numericFromString[T <: String](s: T)(implicit evidence: QueryValue[T]): NumericCol[T] = new NumericCol[T] {}
}
object Hello extends App with Magnets with QueryValueFormats {
//function accept only existentials
def existentialsOnly(coln: NumericCol[_]*): Unit = println("stub")
existentialsOnly(1, "str")//not compiles
}
Он компилируется с 2.12, но с 2.13 - нет:
[error] ..//Hello.scala:21:20: type mismatch;
[error] found : Int(1)
[error] required: example.Hello.NumericCol[_]
[error] existentialsOnly(1, "str")
[error]
Я пытаюсь удалить экзистенциальное (всего несколько попыток):
def existentialsOnly[T: ClassTag](coln: NumericCol[T]*): Unit
И это делает код компилируемым, но если coln
иметь только один тип. Например:
existentialsOnly("str", "str")
Итак, как правильно использовать экзистенциалы в первом случае? Текущее использование неверно для 2.13?
1 ответ
Дело в том, что в 2.13 singleton-типы обрабатываются немного менее консервативно, чем в 2.12.
Ошибка
Error: type mismatch;
found : Int(1)
required: App.Hello.NumericCol[_]
existentialsOnly(1, "str")
означает, что в 2.13 не подразумевается, что 1
в existentialsOnly(1, "str")
имеет тип Int
(и поэтому NumericCol[Int]
из-за неявного преобразования), а не одиночного типа Int(1)
.
Если добавить подсказки
existentialsOnly(1: Int, "str": String)
будет компилироваться в 2.13.
Аналогичным образом можно заменить numericFromInt
а также numericFromString
с участием
implicit def numericFrom[U, T <: U](s: T)(implicit evidence: QueryValue[U]): NumericCol[T] = new NumericCol[T] {}
или
implicit def numericFrom[T](s: T)(implicit evidence: QueryValue[_ >: T]): NumericCol[T] = new NumericCol[T] {}
как в 2.12, так и в 2.13, но с
implicit def numericFrom[T](s: T)(implicit evidence: QueryValue[T]): NumericCol[T] = new NumericCol[T] {}
(без подсказок) только в 2.12.