Как скомпилировать код с типами имплицитов и экзистенциалов в 2.13 - PullRequest
3 голосов
/ 18 марта 2020

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] 

I попробуйте удалить экзистенциалы (только некоторые попытки):

def existentialsOnly[T: ClassTag](coln: NumericCol[T]*): Unit

И это делает код компилируемым, но если coln имеет только один тип. Например:

existentialsOnly("str", "str")

Итак, как правильно использовать экзистенциалы в первом случае? Текущее использование неправильно для 2.13?

1 Ответ

1 голос
/ 26 марта 2020

Похоже, что в 2.13 синглтон-типы обрабатываются немного менее консервативно, чем в 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.

...