Apa yang dimaksud dengan tipe yang bergantung pada jalur Scala?

125

Saya pernah mendengar bahwa Scala memiliki tipe yang bergantung pada jalur. Ini ada hubungannya dengan kelas batin tapi apa sebenarnya artinya ini dan mengapa saya peduli?

oxbow_lakes
sumber
2
@Michel - Saya bahkan tahu apa itu PDT; Saya berharap SO bisa diperkaya dengan jawaban!
oxbow_lakes
1
Saya harap ada jawaban singkat setelah membaca bab 12 tentang PDT
stacker

Jawaban:

165

Contoh favorit saya:

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

Jadi, jenisnya Coordinatebergantung pada instance Boarddari mana ia dibuat. Ada banyak hal yang dapat dilakukan dengan ini, memberikan semacam keamanan tipe yang bergantung pada nilai dan bukan tipe saja.

Ini mungkin terdengar seperti tipe tergantung, tetapi ini lebih terbatas. Misalnya, tipe occupiedbergantung pada nilai Board. Di atas, baris terakhir tidak berfungsi karena jenisnya c2adalah b2.Coordinate, sedangkan occupiedjenisnya adalah Set[b1.Coordinate]. Perhatikan bahwa seseorang dapat menggunakan pengenal lain dengan jenis yang sama b1, jadi bukan pengenal b1 yang terkait dengan jenis tersebut. Misalnya, karya berikut ini:

val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3
Daniel C. Sobral
sumber
2
1 untuk jawabannya. Saya menemukan kalimat terakhir membingungkan: Anda mengatakan 'tipe keamanan yang bergantung pada nilai dan bukan tipe saja'. Bagi saya, ini terdengar seperti tipe dependen, tetapi tipe dependen jalur tidak bergantung pada nilai itu sendiri. Apakah menurut Anda itu membingungkan juga?
Matthew Farwell
4
@Matthew Saya mengerti apa yang Anda katakan, tetapi tipe yang bergantung pada jalur bergantung pada nilai, bahkan jika itu tidak memberikan fleksibilitas yang biasanya terkait dengan tipe dependen.
Daniel C. Sobral
1
Tepat sekali, itulah yang saya maksud. Awalnya saya membaca bahwa tipe bergantung pada nilai yang diteruskan ke konstruktor, bukan b1 / b2. Saya memahaminya sekarang, tetapi saya perlu beberapa kali membaca untuk mendapatkannya.
Matthew Farwell
3
Penjelasan termudah adalah bahwa tipe yang bergantung pada jalur hanyalah kelas dengan penutupan, dengan cara yang persis sama fungsi dapat mengikat variabel dari cakupan.
polkovnikov.ph
1
Tapi mungkin ada satu perbedaan mendasar untuk analogi ini: satu pengikatan terjadi pada waktu proses (untuk penutupan) dan pengikatan lainnya berlangsung pada waktu kompilasi (untuk tipe yang bergantung pada jalur).
jhegedus