Ho sentito che Scala ha tipi dipendenti dal percorso. Ha a che fare con le classi interne, ma cosa significa in realtà e perché me ne importa?
Ho sentito che Scala ha tipi dipendenti dal percorso. Ha a che fare con le classi interne, ma cosa significa in realtà e perché me ne importa?
Risposte:
Il mio esempio preferito:
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
Quindi, il tipo di Coordinate
dipende dall'istanza Board
da cui è stata istanziata. Ci sono tutti i tipi di cose che possono essere realizzati con questo, dando una sorta di sicurezza del tipo che dipende dai valori e non solo dai tipi.
Potrebbe sembrare un tipo dipendente, ma è più limitato. Ad esempio, il tipo di occupied
dipende dal valore di Board
. Sopra, l'ultima riga non funziona perché il tipo di c2
è b2.Coordinate
, mentre occupied
il tipo è Set[b1.Coordinate]
. Si noti che è possibile utilizzare un altro identificatore con lo stesso tipo di b1
, quindi non è l' identificatore b1
associato al tipo. Ad esempio, i seguenti lavori:
val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3