O que o operador `#` significa no Scala?

Eu vejo este código neste blog: Programação em nível de tipo no Scala :

// define the abstract types and bounds trait Recurse { type Next <: Recurse // this is the recursive function definition type X[R <: Recurse] <: Int } // implementation trait RecurseA extends Recurse { type Next = RecurseA // this is the implementation type X[R <: Recurse] = R#X[R#Next] } object Recurse { // infinite loop type C = RecurseA#X[RecurseA] } 

Existe um operador # no código R#X[R#Next] que eu nunca vi. Como é difícil pesquisá-lo (ignorado pelos mecanismos de pesquisa), quem pode me dizer o que isso significa?

Para explicar isso, primeiro temos que explicar classs aninhadas em Scala. Considere este exemplo simples:

 class A { class B def f(b: B) = println("Got my B!") } 

Agora vamos tentar algo com isso:

 scala> val a1 = new A a1: A = A@2fa8ecf4 scala> val a2 = new A a2: A = A@4bed4c8 scala> a2.f(new a1.B) :11: error: type mismatch; found : a1.B required: a2.B a2.f(new a1.B) ^ 

Quando você declara uma class dentro de outra class no Scala, você está dizendo que cada instância dessa class tem essa subclass. Em outras palavras, não há class AB , mas há classs a2.B e a2.B , e são classs diferentes , como a mensagem de erro nos a2.B acima.

Se você não entendeu isso, procure tipos dependentes de caminho.

Agora, # possibilita que você se refira a essas classs aninhadas sem restringi-las a uma instância específica. Em outras palavras, não há AB , mas há A#B , que significa uma class aninhada B de qualquer instância de A

Podemos ver isso no trabalho, alterando o código acima:

 class A { class B def f(b: B) = println("Got my B!") def g(b: A#B) = println("Got a B.") } 

E experimentando:

 scala> val a1 = new A a1: A = A@1497b7b1 scala> val a2 = new A a2: A = A@2607c28c scala> a2.f(new a1.B) :11: error: type mismatch; found : a1.B required: a2.B a2.f(new a1.B) ^ scala> a2.g(new a1.B) Got a B. 

É conhecido como projeção de tipo e é usado para acessar membros do tipo.

 scala> trait R { | type A = Int | } defined trait R scala> val x = null.asInstanceOf[R#A] x: Int = 0 

Basicamente, é uma maneira de se referir a classs dentro de outras classs.

http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html (procure por “libra”)

Aqui está um recurso para procurar em “operadores simbólicos” (que são realmente methods), mas eu não descobri como escaping “#” para procurar no scalex)

http://www.artima.com/pins1ed/book-index.html#indexanchor