I'm reading Scala in depth now. Here is an excerpt from the book:
All path-dependent types are type projections. A path-dependent type
foo.Bar
is rewritten asfoo.type#Bar
by the compiler...In Scala, all type references can be written as projects against named entities. The type scala.String is shorthand for
scala.type#String
where the namescala
refers to the packagescala
and the typeString
is defined by theString
class on the scala package.
Obviously, there isn't scala.String
class, but I failed to reproduce this with Null
.
scala> type N = scala.type#Null
<console>:7: error: type mismatch;
found : type
required: AnyRef
type N = scala.type#Null
So, my questions are as follows. Are path-dependent types type projections? Is it just inner compiler representation or can be expressed in scala code?
Here's a quick REPL session which confirms what Josh wrote,
scala> class Foo { type T = String }
defined class Foo
scala> val foo = new Foo
foo: Foo = Foo@10babe8
scala> implicitly[foo.type#T =:= foo.T]
res0: =:=[foo.T,foo.T] = <function1>
The problem with your scala.type#Null
example is that the prefix scala
is a package prefix rather than being a stable identifier of a value. Arguably it ought to be the latter, but unfortunately it's not ... that's a lingering mismatch between the semantics of Scala packages and Scala objects (in the sense of modules).