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?
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.