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

Type inference fails to determine type parameter of superclass #2272

Closed
scabug opened this issue Aug 20, 2009 · 6 comments
Closed

Type inference fails to determine type parameter of superclass #2272

scabug opened this issue Aug 20, 2009 · 6 comments

Comments

@scabug
Copy link

scabug commented Aug 20, 2009

(Summary is long and possibly confusing, sorry!)

I've looked over the spec and I can't see why the compiler shouldn't find the type of I in stringer:

scala> trait F[I] { def get : I }
defined trait F

scala> implicit def stringer[Fx<:F[I],I](a: Fx) = a.get.toString;
stringer: [Fx <: F[I],I](a: Fx)java.lang.String

scala> class FI extends F[Int] { def get = 42 };
defined class FI

scala> implicit def stringer[Fx<:F[I],I](a: Fx) = a.get.toString;
stringer: [Fx <: F[I],I](a: Fx)java.lang.String

scala> {new FI} toLowerCase
<console>:18: error: value toLowerCase is not a member of FI
      {new FI} toLowerCase

scala> stringer{new FI} toLowerCase
<console>:18: error: inferred type arguments [FI,Nothing] do not
conform to method stringer's type parameter bounds [Fx <: F[I],I]
@scabug
Copy link
Author

scabug commented Aug 20, 2009

Imported From: https://issues.scala-lang.org/browse/SI-2272?orig=1
Reporter: @dlwh

@scabug
Copy link
Author

scabug commented Aug 20, 2009

@adriaanm said:
I think this is an inherent limitation of Scala's type inference algorithm. I don't know the details, but the rule of thumb is that you should avoid constraints that have type variables (type parameters that must be inferred) on both sides (such as Fx <: F[I]).

It works if you define stringer as:

implicit def stringer[I](a: F[I]) = a.get.toString

@scabug
Copy link
Author

scabug commented Aug 20, 2009

@dlwh said:
If it's impossible, it's impossible. (And can be closed as such!) If it were possible, I'd sure like it.

You're right that the example would work with that solution, but this is just a simplified test case. In reality, I have a type F[I] that has many subtypes, and I really want to define an implicit def foo[I,Fx<:F[I]](t: Fx): Wrapper[I,Fx] . For most things I can do foo[Fx<:F[_]], but that solution runs into a few other limitations that I'm trying to simplify into something I can turn into a bug report.

@scabug
Copy link
Author

scabug commented Aug 25, 2009

@odersky said:
It's impossible given the current type inference scheme.

@scabug
Copy link
Author

scabug commented Aug 26, 2009

@adriaanm said:
You can however work around it using implicits (once the fix for #2261 is in trunk -- you can get it now from my github: http://github.com/adriaanm/scala/commits/ticket/2261). Using the compiler in my working copy:

dhcp-10-9-32-075:tmp adriaan$$ /Users/adriaan/git/scala-mirror/build/quick/bin/scala
Welcome to Scala version 2.8.0.r0-b20090826112135 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_13).
Type in expressions to have them evaluated.
Type :help for more information.

scala> trait F[I]
defined trait F

scala> class FInt extends F[Int]
defined class FInt

scala> class FString extends F[String]
defined class FString

scala> class Wrapper[I, Fx](implicit val w: Fx <:< F[I])
defined class Wrapper

scala>   implicit def foo[Fx, I](t: Fx)(implicit w: Fx <:< F[I]): Wrapper[I,Fx] = null.asInstanceOf[Wrapper[I,Fx]]
foo: [Fx,I](t: Fx)(implicit w: <:<[Fx,F[I]])Wrapper[I,Fx]

scala> foo(new FInt)                                                                                              
res1: Wrapper[Int,FInt] = null

Note the inferred return type for res1!

<:< is nothing special, BTW:

  sealed abstract class <:<[-From, +To] extends (From => To)
  implicit def conforms[A]: A <:< A = new (A <:< A) {def apply(x: A) = x}

@scabug
Copy link
Author

scabug commented Sep 1, 2009

@dlwh said:
Thanks Adriaan; that's very clever!

(And thanks for considering the change, Scala folks!)

  • David

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