Search code examples
scalatype-safetyaux-pattern

Reflective call occurred when using Aux pattern with type selection


Consider the following exmaple:

sealed trait Granularity
object Granularity {

  case object Full extends Granularity

  sealed trait Partial extends Granularity {
    type GranularityKey
  }

  case object StringGranularity extends Partial {
    override type GranularityKey = String
  }
}

sealed trait Test{
  type T <: Granularity
}
object Test {

  type Aux[TT <: Granularity] = Test{ type T = TT }

  case object Cmp extends Test{
    override type T = StringGranularity.type
  }

  case object Fll extends Test{
    override type T = Full.type
  }
}
     
case class Tst[Gran <: Partial, T <: Test.Aux[Gran]](t: T#T#GranularityKey)
                                                          ^
                                                          |___Advanced language feature: reflective call

Idea signals about some reflective call occured in the type selection T#T#GranularityKey.

Could you please explain what exactly reflective call would occur here? So is it actually typesafe?


Solution

  • Perhaps, because of next type Aux[TT <: Granularity] = Test{ type T = TT } - basically you say here there is some Test that should have defined type alias T in it. I think compiler logic here similar to Duck Typing in Scala implementation. For instance you can define type Foo{ def bar(): Unit} and try to next

    class FooImpl {
      def bar(): Unit = println("Bar")
    }
    val foo: Foo = new FooImpl
    foo.bar()
    

    As you can see FooImpl does not inherits nothing, but still assignable for type Foo, because it satisfies condition of having method bar, but because of JVM restrictions or byte-code restrictions - foo.bar() invocation will be reflective, meaning though Java Reflection API. But, non the less this approach is completely type-safe.

    Maybe, Idea because of this also thinks that type alias T inside Test trait will be invoked though Reflection API.