Search code examples
scalagenericsinner-classesabstract-type

Using Inner Classes As Type Arguments


I need to use an inner class or abstract type as a type argument for an outer type, such as in the heavily simplified example below:

trait A[T <: Ordered[T]] {
}

class B extends A[C] { //<-- Compiler error, type C not found.
  class C extends Ordered[C] {
  }
}

I've come to a rather thorny design problem in my library, and I don't see any satisfying way to avoid this construction. I've tried a number of different wanys to reference the inner class from the type argument, but to no avail.

My questions are:

  1. Is there any way to reference an inner class from the type argument of an outer class?

  2. If not, is there a logical inconsistency that precludes this, or it simply a limitation of the compiler and language specification?


Solution

  • First of all, you would need to qualify C to be the internal class, for example with a projection:

    class B extends A[B#C] {
      class C extends Ordered[C]
    }
    

    This produces an "illegal cyclic reference", so it is a limitation of the compiler

    You could change the type constructor parameter in A to a type member:

    trait A {
      type T <: Ordered[T]
    }
    
    class B extends A {
      class T extends Ordered[T] {
        def compare(that: T): Int = ???
      }
    }