Was bedeutet der Operator "#" in Scala?


131

Ich sehe diesen Code in diesem Blog: Typ-Level-Programmierung 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]
}

#Der Code enthält einen Operator, den R#X[R#Next]ich noch nie gesehen habe. Wer kann mir sagen, was es bedeutet, da es schwierig ist, es zu suchen (von Suchmaschinen ignoriert)?


1
Das "Pfundzeichen" wird manchmal als "Oktathrop" bezeichnet (diese Google-Suche hat mich auf diese Seite gebracht).
Philwalk


Was ist mit anderen Operatoren wie # + und # - (siehe github.com/tpolecat/doobie/blob/series/0.4.x/yax/h2/src/main/… )? Gibt es eine umfassende Liste?
Markus Barthlen

Antworten:


240

Um es zu erklären, müssen wir zuerst verschachtelte Klassen in Scala erklären. Betrachten Sie dieses einfache Beispiel:

class A {
  class B

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

Versuchen wir jetzt etwas damit:

scala> val a1 = new A
a1: A = A@2fa8ecf4

scala> val a2 = new A
a2: A = A@4bed4c8

scala> a2.f(new a1.B)
<console>:11: error: type mismatch;
 found   : a1.B
 required: a2.B
              a2.f(new a1.B)
                   ^

Wenn Sie eine Klasse in einer anderen Klasse in Scala deklarieren, sagen Sie, dass jede Instanz dieser Klasse eine solche Unterklasse hat. Mit anderen Worten, es gibt keine A.BKlasse, aber es gibt a1.Bund a2.BKlassen, und sie sind verschiedene Klassen, wie die Fehlermeldung oben sagt.

Wenn Sie das nicht verstanden haben, suchen Sie nach pfadabhängigen Typen.

Jetzt #können Sie auf solche verschachtelten Klassen verweisen, ohne sie auf eine bestimmte Instanz zu beschränken. Mit anderen Worten, es gibt keine A.B, aber es gibt A#Beine Bverschachtelte Klasse einer beliebigen Instanz von A.

Wir können dies in der Arbeit sehen, indem wir den obigen Code ändern:

class A {
  class B

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

Und probieren Sie es aus:

scala> val a1 = new A
a1: A = A@1497b7b1

scala> val a2 = new A
a2: A = A@2607c28c

scala> a2.f(new a1.B)
<console>:11: error: type mismatch;
 found   : a1.B
 required: a2.B
              a2.f(new a1.B)
                   ^

scala> a2.g(new a1.B)
Got a B.

Exzellentes Beispiel. Ich akzeptiere vollkommen, dass es so funktioniert, aber schwer zu verstehen: scala> classOf [A # B] res7: Klasse [A # B] = Klasse A $ B scala> classOf [aB] res8: Klasse [aB] = Klasse A. $ B. was bedeutet, dass sie tatsächlich den gleichen Typ haben?
Chiron

2
Ihre Werte haben dieselbe Zeichenfolgendarstellung - und sie können sogar gleich sein. Classist eine Laufzeitdarstellung von Java-Klassen und selbst in Java eingeschränkt. Zum Beispiel List<String>und List<Integer>haben die gleiche Laufzeit Class. Wenn Classes nicht reich genug ist, um Java- Typen darzustellen , ist es bei der Darstellung von Scala- Typen fast nutzlos . Wiederum ist res7: Class[A#B] = class A$Blinks vom Gleichheitszeichen ein Typ, rechts vom Gleichheitszeichen, wenn ein Wert die Java- Laufzeitdarstellung einer Klasse ist.
Daniel C. Sobral

13

Es wird als Typprojektion bezeichnet und für den Zugriff auf Typmitglieder verwendet.

scala> trait R {
     |   type A = Int
     | }
defined trait R

scala> val x = null.asInstanceOf[R#A]
x: Int = 0

6
Dies ist keine Antwort. Es zeigt im Grunde den gleichen Code wie die Frage, nur leicht gekürzt. Was ist zum Beispiel der Unterschied zur Punktnotation? Wo würde ich dieses # in echtem Code verwenden?
notan3xit

2
@ notan3xit Vielleicht ist es keine Antwort auf das, was du fragen wolltest. Aber was Sie gefragt haben, ist "... was ich noch nie gesehen habe. Da es schwierig ist, es zu suchen (von Suchmaschinen ignoriert), wer kann mir sagen, was es bedeutet?"
Nafg


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.