He oído que Scala tiene tipos dependientes de la ruta. Tiene algo que ver con las clases internas, pero ¿qué significa esto realmente y por qué me importa?
He oído que Scala tiene tipos dependientes de la ruta. Tiene algo que ver con las clases internas, pero ¿qué significa esto realmente y por qué me importa?
Respuestas:
Mi ejemplo favorito:
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
Entonces, el tipo de Coordinate
depende de la instancia de la Board
que se instancia. Hay todo tipo de cosas que se pueden lograr con esto, dando una especie de seguridad de tipo que depende de los valores y no solo de los tipos.
Esto puede sonar como tipos dependientes, pero es más limitado. Por ejemplo, el tipo de occupied
depende del valor de Board
. Arriba, la última línea no funciona porque el tipo de c2
es b2.Coordinate
, mientras que occupied
el tipo es Set[b1.Coordinate]
. Tenga en cuenta que se puede usar otro identificador con el mismo tipo de b1
, por lo que no es el identificador b1
asociado con el tipo. Por ejemplo, lo siguiente funciona:
val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3