Как скомпилировать код с имплицитными и экзистенциальными типами с помощью 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.

Другие вопросы по тегам