scalascala-compilerscala-2.12

How to override value when value types have a different number of type parameters?


Why does this happily compile,

class Foo[T]

class DerivedFoo[T] extends Foo[T]

class Bar(val foo: Foo[_])

class DerivedBar(override val foo: DerivedFoo[_]) extends Bar(foo)

while this does not?

class OtherDerivedFoo[T, U] extends Foo[T]

class OtherDerivedBar(override val foo: OtherDerivedFoo[_, _]) extends Bar(foo)
//error: value foo overrides nothing

Is there a workaround? Thanks.


Solution

  • Workaround:

    Currently, I cannot quite articulate why it works, but it works:

    import scala.language.existentials
    class DerivedFoo2[T, U] extends Foo[T]
    class DerivedBar2(
      override val foo: (Foo[X] with DerivedFoo2[X, _]) forSome { type X }
    ) extends Bar(foo)
    

    (I've replaced OtherDerivedFoo by DerivedFoo2, see renaming notice below)

    Renaming

    I have renamed the classes as follows, to emphasize the parallels between the two cases, and to make the code of the workaround shorter:

    Assuming that you have

    class Foo[T]
    class Bar(val foo: Foo[_])
    

    This compiles:

    class DerivedFoo1[T] extends Foo[T]
    class DerivedBar1(override val foo: DerivedFoo1[_])    extends Bar(foo)
    

    But this doesn't:

    class DerivedFoo2[T, U] extends Foo[T]
    class DerivedBar2(override val foo: DerivedFoo2[_, _]) extends Bar(foo)