scalatype-members

Type mismatch for type members of class value parameter


Why usage of type members bound to class value parameters generates a "type mismatch" error? For example:

scala> class A { type t }
defined class A

scala> class B(val a: A)
defined class B

scala> val aInt = new A { type t = Int }
aInt: A{type t = Int} = $anon$1@6ccc7368

scala> val b = new B(aInt)
b: B = B@834518

scala> val i: b.a.t = 1
<console>:11: error: type mismatch;
 found   : Int(1)
 required: b.a.t
       val i: b.a.t = 1
                      ^

The strange thing is that when I use a value which is not defined as a class parameter everything works fine:

scala> abstract class C { val a: A }
defined class C

scala> val c = new C { val a = aInt }
c: C{val a: A{type t = Int}} = $anon$1@1e815aad

scala> val i: c.a.t = 1
i: c.a.t = 1

What is the reason for such behaviour?


Solution

  • Seems like I've understood what's happening. In the example with class B the value a is converted to type A which has no definite value for type t. In the example with abstract class C the instance c overrides the value of a with aInt which has a concrete type for t. In other words, c is not an instance of C: it's an instance of its anonymous subclass.

    If I change the example stating the type of c as C explicitly then I get the same error as in the first case:

    scala> class A { type t }
    defined class A
    
    scala> val aInt = new A { type t = Int }
    aInt: A{type t = Int} = $anon$1@3b8590c5
    
    scala> abstract class C { val a: A }
    defined class C
    
    scala> val c: C = new C { val a = aInt }
    c: C = $anon$1@5f14a3c6
    
    scala> val i: c.a.t = 1
    <console>:11: error: type mismatch;
     found   : Int(1)
     required: c.a.t
           val i: c.a.t = 1
                          ^