Why doesn't scala combine this lambda type with the base type?

trait A { type T def test(t: T): Unit } case class B[S <: A](a: S, t : S#T) { def test() = a.test(t) // Error: type mismatch; // found : B.this.t.type (with underlying type S#T) // required: B.this.aT } 

Is it wrong to expect the above to compile? Can my code be fixed?

+6
scala existential-type
source share
3 answers

The compiler does not have sufficient evidence that S#T can be used as an argument to test in a particular instance.

Consider this hypothetical example for the weakened scala compiler

 trait A2 extends A{ type T <: AnyRef } class A3 extends A2{ override type T = Integer def test(t: Integer): Unit = println(t * 2) } 

So, B[A2] must accept an instance of A3 along with everything that is <: AnyRef , while A3 needs Integer precision for its implementation of test

You can catch a specific type in definition B to see which type will be used

 case class B[S <: A, ST](a: S {type T = ST}, t: ST) { def test() = a.test(t) } 
+8
source share

I could come up with encodings (removed type parameters for simplification):

 scala> :paste // Entering paste mode (ctrl-D to finish) def test0(a: A)(t : aT) = a.test(t) abstract class B{ val a: A val t: aT def test = a.test(t) } // Exiting paste mode, now interpreting. test0: (a: A)(t: aT)Unit defined class B 

This, on the other hand, did not work with class class arguments (and not classes).

One of the reasons your encoding is not working:

 scala> def test1(a: A)(t : A#T) = a.test(t) <console>:12: error: type mismatch; found : t.type (with underlying type A#T) required: aT def test1(a: A)(t : A#T) = a.test(t) 

The important part required: aT (compared to A#T ). The validation method in A does not accept any T, it takes T this.T , or, in other words, T belonging to one particular instance of A.

+2
source share

Instead of projecting a type, you can use the dependent type aT :

 trait A { type T def test(t: T): Unit } case class B[S <: A](a: S)(t : aT) { def test() = a.test(t) } 
+1
source share

All Articles