zella
zella

Reputation: 4685

How to compile code with implicits and existentials types with 2.13

upd I have a function that accepts types with existentials:

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
}

It compiles with 2.12, but with 2.13 - not:

[error] ..//Hello.scala:21:20: type mismatch;
[error]  found   : Int(1)
[error]  required: example.Hello.NumericCol[_]
[error]   existentialsOnly(1, "str")
[error] 

I try to remove existentials(Just some tryings):

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

And this make code compilable, but if coln have single type only. E.g:

existentialsOnly("str", "str")

So, how properly use existentials in first case? Does current usage wrong for 2.13?

Upvotes: 3

Views: 203

Answers (1)

Dmytro Mitin
Dmytro Mitin

Reputation: 51693

The thing seems to be that in 2.13 singleton types are treated a little less conservatively than in 2.12.

The error

Error: type mismatch;
 found   : Int(1)
 required: App.Hello.NumericCol[_]
    existentialsOnly(1, "str")

means that in 2.13 it's not inferred that 1 in existentialsOnly(1, "str") has type Int (and therefore NumericCol[Int] because of implicit conversion) rather than singleton type Int(1).

If you add hints

existentialsOnly(1: Int, "str": String)

will compile in 2.13.

Similarly you can replace numericFromInt and numericFromString with

implicit def numericFrom[U, T <: U](s: T)(implicit evidence: QueryValue[U]): NumericCol[T] = new NumericCol[T] {}

or

implicit def numericFrom[T](s: T)(implicit evidence: QueryValue[_ >: T]): NumericCol[T] = new NumericCol[T] {}

in both 2.12 and 2.13 but with

implicit def numericFrom[T](s: T)(implicit evidence: QueryValue[T]): NumericCol[T] = new NumericCol[T] {}

(without hints) only in 2.12.

Upvotes: 1

Related Questions