Je m'intéresse au problème de la conformité d'un type spécifique à un type structurel plus général. Prenons les exemples suivants:Conformité de type de structure généralisée dans Scala
trait Sup
trait Sub extends Sup
type General = {
def contra(o: Sub): Unit
def co(): Sup
def defaults(age: Int): Unit
def defaults2(age: Int): Unit
def defaults3(first: String): Unit
}
trait Specific {
def contra(o: Sup): Unit // doesn't conform
def co(): Sub // conforms
def defaults(age: Int, name: String = ""): Unit // doesn't conform
def defaults2(name: String = "", age: Int = 0): Unit // doesn't conform
def defaults3(first: String = "", last: String = ""): Unit // doesn't conform
}
Dans chacun des cas non conformes, un appel à la méthode General
peut être résolu en toute sécurité à la méthode correspondante Specific
. Un exemple pratique plus intéressant se trouve dans this question:
trait Versionable[T] {
self: { def copy(version: Int): T } =>
val version = 0
def incrementVersion = copy(version = version + 1)
}
case class Customer(name: String, override val version: Int)
extends Versionable[Customer] {
def changeName(newName: String) = copy(name = newName)
}
Ici, la méthode du client copy
ne se conforme pas à la signature dans l'annotation auto-type de versionnable. Notez, cependant, que si le compilateur est autorisé, copy
pourrait être invoqué comme il est dans Versionable.incrementVersion
. De toute évidence, la signature réelle de la méthode copy
du Client est trop spécifique pour être utilisée dans Versionable, car elle porte la connaissance non pertinente que l'on peut éventuellement fournir un paramètre name
.
Existe-t-il des moyens de contourner ces limitations? Y a-t-il des raisons pour lesquelles une telle conformité généralisée serait une mauvaise idée?
Un autre exemple pratique: http://stackoverflow.com/questions/4410469/refactoring-copy-functionality –