Что подразумевается под типами Scala, зависящими от пути?

125

Я слышал, что в Scala есть типы, зависящие от пути. Это как-то связано с внутренними классами, но что это на самом деле означает и почему меня это волнует?

oxbow_lakes
источник
2
@Michel - я даже знаю, что такое PDT; Я надеялся, что ТАК может быть обогащен ответом!
oxbow_lakes
1
Я надеюсь , что это сжато ответ после прочтения CH12 о PDT
укладчик

Ответы:

165

Мой любимый пример:

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

Итак, тип Coordinateзависит от экземпляра, Boardиз которого он был создан. С его помощью можно сделать все, что угодно, обеспечивая своего рода безопасность типов, которая зависит от значений, а не только от типов.

Это может показаться зависимым типом, но оно более ограничено. Например, тип occupiedзависит от значения Board. Выше последняя строка не работает, потому что тип c2- b2.Coordinate, а occupiedтип - Set[b1.Coordinate]. Обратите внимание, что можно использовать другой идентификатор с тем же типом b1, поэтому это не идентификатор b1 , связанный с типом. Например, работает следующее:

val b3: b1.type = b1
val c3 = b3.Coordinate(10, 10)
b1.occupied += c3
Дэниел С. Собрал
источник
2
+1 за ответ. Последнее предложение меня сбивает с толку: вы говорите «безопасность типов, которая зависит от значений, а не только от типов». Для меня это звучит как зависимые типы, но зависимые от пути типы не зависят от значений как таковых. Вы думаете, что это тоже сбивает с толку?
Мэтью Фарвелл,
4
@Matthew Я понимаю, о чем вы говорите, но типы , зависящие от пути , зависят от значений, даже если они не обеспечивают гибкости, обычно связанной с зависимыми типами.
Дэниел С. Собрал,
1
Именно это я и имел в виду. Сначала я прочитал, что тип зависит от значений, передаваемых конструктору, а не от b1 / b2. Теперь я понимаю это, но мне потребовалось несколько прочтений, чтобы понять это.
Мэтью Фарвелл,
3
Самое простое объяснение состоит в том, что типы, зависящие от пути, - это просто классы с замыканиями, точно так же, как функции могут связывать переменные из области видимости.
polkovnikov.ph
1
Но, возможно, в этой аналогии есть одно фундаментальное отличие: одна привязка происходит во время выполнения (для замыканий), а другая привязка происходит во время компиляции (для типов, зависящих от пути).
jhegedus 04