Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implicit view does not work if the view requires another implicit parameter #8380

Closed
scabug opened this issue Mar 8, 2014 · 7 comments
Closed

Comments

@scabug
Copy link

scabug commented Mar 8, 2014

class ImplicitNotFound {

  def main(arguments: Array[String]) {
    {
      implicit def view[A]: A => Array[A] = ???
      val seq: Array[Int] = 1
    }

    {
      implicit def view[A: Manifest]: A => Array[A] = ???
      val seq: Array[Int] = 1 // type mismatch;  found   : Int(1)  required: Array[Int]
    }
  }
}
@scabug
Copy link
Author

scabug commented Mar 8, 2014

Imported From: https://issues.scala-lang.org/browse/SI-8380?orig=1
Reporter: @Atry
Affected Versions: 2.10.3

@scabug
Copy link
Author

scabug commented Mar 10, 2014

@adriaanm said (edited on Mar 10, 2014 10:00:22 PM UTC):
The second version should be

 implicit def view[A: Manifest](x: A):  Array[A] = ???

@scabug scabug closed this as completed Mar 10, 2014
@scabug
Copy link
Author

scabug commented Mar 11, 2014

@Atry said:
In Scala Reference, 7.3 Views:

1. If an expression e is of type T , and T does not conform to the expression’s expected type pt. In this case an implicit v is searched which is applicable to e and whose result type conforms to pt. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of T => pt. If such a view is found, the expression e is converted to v(e).

I think implicit def view[A: Manifest]: A => Array[A] corresponds T => pt. And it even works as implicit parameter:

implicit def view[A: Manifest]: A => Array[A] = ???
implicitly[Int => Array[Int]] // No compiler error!

@scabug
Copy link
Author

scabug commented Mar 11, 2014

@adriaanm said:
It may "work", but it's not going to do what you want because the order of the arguments is swapped, and type inference proceeds left to right per argument list (and per implicit argument within the implicit argument list):

Your version is the polymorphic type: [A](implicit ev: Manifest[A]): A => Array[A], where inference will attempt to infer A from an implicit that's applicable for ev. Once A is inferred (to Nothing), you'll end up with a view from Nothing => Array[Nothing].

The version I proposed swaps the order around, so that x's actual type will drive inference of A: [A](x: A)(implicit ev: Manifest[A]): Array[A]

@scabug
Copy link
Author

scabug commented Mar 11, 2014

@adriaanm said:
To be clear, the implicitly[Int => Array[Int]] is not directly related to the implicit that's searched to convert 1 to an Array[Int], as A hasn't been inferred yet, so we're looking for implicitly[A => Array[A]], where A is undetermined.

@scabug
Copy link
Author

scabug commented Mar 11, 2014

@Atry said:
What you said is different from Scala Reference.
Scala Reference said, the type T and the expected type pt are determined before the compiler searches for an implicit view.

@scabug
Copy link
Author

scabug commented Mar 12, 2014

@adriaanm said:
You're right. I apologize for the lacking specification. I'm working on updating it in preparation of the 2.11.0 final.
When it comes to type inference and implicit search, the implementation unfortunately is the specification.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant