¿Qué significa el operador `#` en Scala?

Veo este código en este blog: Progtwigción a nivel de tipo en 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] } 

Hay un operador # en el código R#X[R#Next] que nunca he visto. Como es difícil buscarlo (ignorado por los motores de búsqueda), ¿quién puede decirme qué significa?

Para explicarlo, primero tenemos que explicar las clases anidadas en Scala. Considera este simple ejemplo:

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

Ahora intentemos algo con esto:

 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) ^ 

Cuando declaras una clase dentro de otra clase en Scala, estás diciendo que cada instancia de esa clase tiene dicha subclase. En otras palabras, no hay clases AB , pero hay clases a1.B y a2.B , y son clases diferentes , como nos dice el mensaje de error anterior.

Si no lo entendió, busque los tipos que dependen de la ruta.

Ahora, # hace posible que se refiera a tales clases anidadas sin restringirlo a una instancia particular. En otras palabras, no hay AB , pero hay A#B , lo que significa una clase anidada B de cualquier instancia de A

Podemos ver esto en el trabajo cambiando el código anterior:

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

Y probándolo:

 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. 

Se conoce como proyección de tipo, y se usa para acceder a miembros de tipo.

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

Básicamente, es una forma de referirse a clases dentro de otras clases.

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

Aquí hay un recurso para buscar en “operadores simbólicos” (que en realidad son métodos), pero no he descubierto cómo escapar “#” para buscar en scalex)

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