Cosa significa l’operatore `# in Scala?

Vedo questo codice in questo blog: programmazione a livello di codice in 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] } 

C’è un operatore # nel codice R#X[R#Next] che non ho mai visto. Dal momento che è difficile ricercarlo (ignorato dai motori di ricerca), chi può dirmi cosa significa?

    Per spiegarlo, dobbiamo prima spiegare le classi nidificate in Scala. Considera questo semplice esempio:

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

    Ora proviamo qualcosa con questo:

     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 dichiari una class all’interno di un’altra class in Scala, stai dicendo che ogni istanza di quella class ha una tale sottoclass. In altre parole, non esiste una class AB , ma ci sono classi a1.B e a2.B e sono classi diverse , come ci dice il messaggio di errore sopra.

    Se non l’hai capito, cerca i tipi dipendenti dal percorso.

    Ora, # rende ansible fare riferimento a tali classi annidate senza limitarlo a una particolare istanza. In altre parole, non c’è AB , ma c’è A#B , che significa una class nidificata in B di qualsiasi istanza di A

    Possiamo vedere questo in azione cambiando il codice qui sopra:

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

    E provandolo:

     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. 

    È noto come tipo proiezione e viene utilizzato per accedere ai membri del tipo.

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

    Fondamentalmente, è un modo di riferirsi a classi all’interno di altre classi.

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

    Ecco una risorsa per la ricerca su “operatori simbolici” (che sono davvero metodi), ma non ho capito come sfuggire “#” per cercare su in scalax)

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