Was ist mit Scalas pfadabhängigen Typen gemeint?

125

Ich habe gehört, dass Scala pfadabhängige Typen hat. Es hat etwas mit Innenklassen zu tun, aber was bedeutet das eigentlich und warum kümmert es mich?

oxbow_lakes
quelle
2
@Michel - Ich weiß sogar, was PDTs sind; Ich hatte gehofft, dass SO mit einer Antwort bereichert werden kann!
oxbow_lakes
1
Ich hoffe, es gibt eine knappe Antwort nach dem Lesen von Kapitel 12 über PDT
Stapler

Antworten:

165

Mein Lieblingsbeispiel:

case class Board(length: Int, height: Int) {
  case class Coordinate(x: Int, y: Int) { 
    require(0 <= x && x < length && 0 <= y && y < height) 
  }
  val occupied = scala.collection.mutable.Set[Coordinate]()
}

val b1 = Board(20, 20)
val b2 = Board(30, 30)
val c1 = b1.Coordinate(15, 15)
val c2 = b2.Coordinate(25, 25)
b1.occupied += c1
b2.occupied += c2
// Next line doesn't compile
b1.occupied += c2

Die Art von Coordinatehängt also von der Instanz ab, Boardvon der es instanziiert wurde. Es gibt alle möglichen Dinge, die damit erreicht werden können und eine Art Typensicherheit bieten, die von Werten und nicht nur von Typen abhängt.

Dies mag nach abhängigen Typen klingen, ist jedoch eingeschränkter. Zum Beispiel ist der Typ von occupiedabhängig vom Wert von Board. Oben funktioniert die letzte Zeile nicht, weil der Typ von c2ist b2.Coordinate, während occupiedder Typ ist Set[b1.Coordinate]. Beachten Sie, dass ein anderer Bezeichner mit demselben Typ von verwendet werden kann b1, sodass dem Typ nicht der Bezeichner zugeordnet b1 ist. Zum Beispiel funktioniert Folgendes:

val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3
Daniel C. Sobral
quelle
2
+1 für die Antwort. Ich fand den letzten Satz verwirrend: Sie sagen "Typensicherheit, die von Werten abhängt und nicht nur von Typen". Für mich klingt dies nach abhängigen Typen, aber pfadabhängige Typen hängen nicht von Werten an sich ab. Findest du es auch verwirrend?
Matthew Farwell
4
@Matthew Ich verstehe , was Sie sagen, aber pfadabhängige Arten tun , hängt von Werten, auch wenn es nicht die Flexibilität , die normalerweise mit abhängigen Typen zugeordnet liefert.
Daniel C. Sobral
1
Genau das meine ich. Anfangs habe ich gelesen, dass der Typ von den an den Konstruktor übergebenen Werten abhängt, nicht von b1 / b2. Ich verstehe es jetzt, aber ich brauchte ein paar Lesungen, um es zu bekommen.
Matthew Farwell
3
Die einfachste Erklärung ist, dass pfadabhängige Typen nur Klassen mit Abschlüssen sind, genauso wie Funktionen Variablen aus dem Bereich binden können.
polkovnikov.ph
1
Aber vielleicht gibt es einen grundlegenden Unterschied zu dieser Analogie: Eine Bindung findet zur Laufzeit (für Abschlüsse) und die andere zur Kompilierungszeit (für pfadabhängige Typen) statt.
Jhegedus