This page is no longer maintained — Please continue to the home page at www.scala-lang.org

A Question about Type Constructor Inference

2 replies
Kota Mizushima
Joined: 2009-09-07,
User offline. Last seen 42 years 45 weeks ago.

Hi.

I have some questions about type constructor inference algorithm of Scala.

Yesterday, my acquaintance said that it seems strange behavior that
the following
code doesn't compile successfully (in Scala 2.9.1.final).

class K {
trait A[T] { def t : T }
trait B extends A[Int]
def g[T, C[X] <: A[X]](a : C[T]) = a
def f[C[_] <: A[_]](a : C[_]) = a
g(new B { def t = 1 } : B) // ok
g(new B { def t = 1 }) // error
}

The error messages are as followings.

>>>
K.scala:7: error: type mismatch;
found : java.lang.Object with K.this.B
required: ?C[?T]
Note that implicit conversions are not applicable because they are ambiguous:
both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A]
and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
are possible conversion functions from java.lang.Object with K.this.B to ?C[?T]

g(new B { def t = 1 }) // error
^
one error found
<<<

Because I don't understand the reason why the program doesn't compile,
I tried to compile
the above code with -Yinfer-debug. Then, the following message was found.

...
inferMethodInstance {
fn K.this.g[T, C]
undetparams type T, type C
args {
final class $anon extends java.lang.Object with K.this.B {
def this(): anonymous class $anon = {
$anon.super.this();
()
};
def t: Int = 1
};
new $anon()
}
pt0 ?
}
methTypeArgs {
tparams type T, type C
formals C[T]
restpe C[T]
restpeInst ?C[?T]
argtpes java.lang.Object with K.this.B
pt ?
tvars ?T, ?C
constraints [ _>:() | _<:() ] _= , [ _>:() | _<:() ] _=
}
[inferImplicit view] pt = java.lang.Object with K.this.B => ?C[?T]
Implicit search in Context(K.@Apply scope=835328616) {
search java.lang.Object with K.this.B => ?C[?T]
target
isView true
eligible any2ArrowAssoc: [A](x: A)ArrowAssoc[A]
eligible any2Ensuring: [A](x: A)Ensuring[A]
}
...

It seems that a type constructor inference fails about the expression
"g(new B { def t = 1 })".
Then, I read the Scala Language Specification 2.9 to find the
specification about type
constructor inference. However, I didn't find the specification of
type constructor parameter
inference in it.

Although I understand that Scala' type constructor inference doesn't
have completeness,
I want to know the reason why the above code doesn't compile.

Are there some resources about the specification of Scala's type
constructor inference ?

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: A Question about Type Constructor Inference
It compiles in trunk.  I fixed it by not inferring anonymous classes (because this used to infer "$anon-whatever" in the second case, with obvious problems arising afterward.)
On Wed, Jan 18, 2012 at 7:08 AM, Kota Mizushima <mizukota [at] gmail [dot] com> wrote:
Yesterday, my acquaintance said that it seems strange behavior that
the following
code doesn't compile successfully (in Scala 2.9.1.final).

class K {
 trait A[T] { def t : T }
 trait B extends A[Int]
 def g[T, C[X] <: A[X]](a : C[T]) = a
 def f[C[_] <: A[_]](a : C[_]) = a
 g(new B { def t = 1 } : B) // ok
 g(new B { def t = 1 }) // error
}

Kota Mizushima
Joined: 2009-09-07,
User offline. Last seen 42 years 45 weeks ago.
Re: A Question about Type Constructor Inference

Thanks for the quick reply. I didn't try to compile the code in trunk.

I'm pleased that the code compiles in trunk by your fix and I've understood
how to fix this problem roughly.

2012/1/19 Paul Phillips :
> It compiles in trunk.  I fixed it by not inferring anonymous classes
> (because this used to infer "$anon-whatever" in the second case, with
> obvious problems arising afterward.)
>
> On Wed, Jan 18, 2012 at 7:08 AM, Kota Mizushima wrote:
>>
>> Yesterday, my acquaintance said that it seems strange behavior that
>> the following
>> code doesn't compile successfully (in Scala 2.9.1.final).
>>
>> class K {
>>  trait A[T] { def t : T }
>>  trait B extends A[Int]
>>  def g[T, C[X] <: A[X]](a : C[T]) = a
>>  def f[C[_] <: A[_]](a : C[_]) = a
>>  g(new B { def t = 1 } : B) // ok
>>  g(new B { def t = 1 }) // error
>> }
>
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland