J'ai entendu dire que Scala avait des types dépendants du chemin. Cela a quelque chose à voir avec les inner-classes, mais qu'est-ce que cela signifie réellement et pourquoi cela m'intéresse-t-il ?
Réponse
Trop de publicités?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 duquel il a été instancié. Il y a toutes sortes de choses qui peuvent être accomplies avec ceci, donnant une sorte de sécurité de type qui dépend des valeurs et pas seulement des types.
Cela peut ressembler à des types dépendants, mais c'est plus limité. Par exemple, le type occupied
dépend de la valeur de Board
. Ci-dessus, la dernière ligne ne fonctionne pas parce que le type de c2
est b2.Coordinate
alors que occupied
Le type de l'utilisateur 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 le identifiant b1
qui est associé au type. Par exemple, la formule suivante fonctionne :
val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3