J'ai entendu dire que Scala a des types dépendants du chemin. C'est quelque chose à voir avec les classes internes, mais qu'est-ce que cela signifie réellement et pourquoi est-ce que je m'en soucie?
Mon exemple préféré:
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
Ainsi, le type de Coordinate
dépend de l'instance de Board
à partir de laquelle il a été instancié. Il y a toutes sortes de choses qui peuvent être accomplies avec cela, donnant une sorte de sécurité de type qui dépend des valeurs et non des types seuls.
Cela peut ressembler à des types dépendants, mais il est plus limité. Par exemple, le type de occupied
dépend de la valeur de Board
. Ci-dessus, la dernière ligne ne fonctionne pas car le type de c2
est b2.Coordinate
, tandis que le type de occupied
est Set[b1.Coordinate]
. Notez que l'on peut utiliser un autre identifiant avec le même type de b1
, donc ce n'est pas identifiantb1
associé au type. Par exemple, les travaux suivants:
val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3