¿Qué se entiende por tipos dependientes de la ruta de Scala?

125

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?

oxbow_lakes
fuente
2
@Michel: incluso sé qué son los PDT; ¡Esperaba que SO pudiera enriquecerse con una respuesta!
oxbow_lakes
1
Espero que haya una respuesta clara después de leer el capítulo 12 sobre PDT
apilador

Respuestas:

165

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 Coordinatedepende de la instancia de la Boardque 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 occupieddepende del valor de Board. Arriba, la última línea no funciona porque el tipo de c2es b2.Coordinate, mientras que occupiedel 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
Daniel C. Sobral
fuente
2
+1 por la respuesta. La última oración me pareció confusa: dices 'seguridad de tipos que depende de valores y no solo de tipos'. Para mí, esto suena como tipos dependientes, pero los tipos dependientes de la ruta no dependen de los valores per se. ¿Crees que también es confuso?
Matthew Farwell
44
@Matthew entiendo lo que está diciendo, pero dependiente de la trayectoria tipos hacerlo dependen de los valores, incluso si no proporciona la flexibilidad que normalmente se asocian con tipos dependientes.
Daniel C. Sobral
1
Exactamente, eso es lo que quiero decir. Inicialmente leí que el tipo dependía de los valores pasados ​​al constructor, no del b1 / b2. Ahora lo entiendo, pero me tomó algunas lecturas conseguirlo.
Matthew Farwell
3
La explicación más fácil es que los tipos dependientes de la ruta son solo clases con cierres, exactamente de la misma manera que las funciones pueden unir variables desde el alcance.
polkovnikov.ph
1
Pero tal vez haya una diferencia fundamental en esta analogía: un enlace tiene lugar en tiempo de ejecución (para cierres) y el otro enlace tiene lugar en tiempo de compilación (para tipos dependientes de ruta).
jhegedus