Ouvi dizer que Scala tem tipos dependentes de caminho. Tem algo a ver com classes internas, mas o que isso realmente significa e por que eu me importo?
Ouvi dizer que Scala tem tipos dependentes de caminho. Tem algo a ver com classes internas, mas o que isso realmente significa e por que eu me importo?
Respostas:
Meu exemplo 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
Portanto, o tipo de Coordinatedepende da instância da Boardqual foi instanciado. Há todo tipo de coisa que pode ser realizada com isso, fornecendo um tipo de segurança de tipo dependente de valores e não apenas de tipos.
Pode parecer tipos dependentes, mas é mais limitado. Por exemplo, o tipo de occupiedé dependente do valor de Board. Acima, a última linha não funciona porque o tipo de c2é b2.Coordinate, enquanto occupiedo tipo é Set[b1.Coordinate]. Observe que é possível usar outro identificador com o mesmo tipo de b1, portanto, não é o identificador b1 associado ao tipo. Por exemplo, o seguinte funciona:
val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3