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?
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?
Antworten:
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