Sono interessato al problema di conformare un tipo specifico a un tipo strutturale più generale. Considerare i seguenti esempi:Conformità di tipo strutturale generalizzata in 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
}
In ciascuno dei casi non conformi, una chiamata al metodo General
può tranquillamente essere risolto al metodo corrispondente Specific
. Un esempio pratico più interessante può essere trovato in 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)
}
Qui, il metodo del Cliente copy
non è conforme alla firma in auto-tipo di annotazione di versionable. Si noti, tuttavia, che se il compilatore è consentito, copy
può essere richiamato così come è in Versionable.incrementVersion
. Chiaramente, la firma effettiva del metodo copy
del cliente è troppo specifica per l'uso in Versionable, poiché contiene la conoscenza irrilevante che si può facoltativamente fornire un parametro name
.
Esistono modi per aggirare queste limitazioni? Ci sono ragioni per cui una simile generalizzazione sarebbe una cattiva idea?
Un altro esempio pratico: http://stackoverflow.com/questions/4410469/refactoring-copy-functionality –