J'ai emprunté l'astuce MyType de Landeihere. Mais récemment, j'ai rencontré un problème avec le type de soi. Un exemple montre ce que je veux dire:MyType Type Incompatibilité
trait Excitable[SELF] { self: SELF =>
def withMoreAnger: SELF
}
trait Animal[SELF0] { self: SELF0 =>
type SELF = SELF0 // to reveal SELF0 for method spitAt used as a dependent method type
type SpittableAnimal[S] <: Animal[S]
def spitAt[A <: SpittableAnimal[_]](a: A): a.SELF
}
trait ExcitableAnimal[SELF] extends Animal[SELF] with Excitable[SELF] { self: SELF =>
type SpittableAnimal[S] = ExcitableAnimal[S]
def spitAt[A <: SpittableAnimal[_]](a: A): a.SELF = a.withMoreAnger
}
trait Quadruped[SELF] extends ExcitableAnimal[SELF] { self: SELF => }
case class Dog(anger: Int) extends Quadruped[Dog] {
def withMoreAnger: Dog = copy(anger = anger + 1)
}
case class Cat(anger: Int) extends Quadruped[Cat] {
def withMoreAnger: Cat = copy(anger = anger + 1)
}
val dog = Dog(anger = 0)
val cat = Cat(anger = 0)
val angryCat: Cat = dog spitAt cat // fine
val anotherDog = Dog(0)
val animals = Seq(dog, cat)
val angryAnimals: Seq[Quadruped[_]] = for (a <- animals) yield anotherDog spitAt a // fine
val veryAngryAnimals: Seq[Quadruped[_]] = for (a <- angryAnimals) yield anotherDog spitAt a // type mismatch !!!
Pour autant que je peux le révéler, le problème semble être que le trait de soulignement dans la méthode spitAt
donne un Any
pour a.SELF
à la fin. Mais comment puis-je faire fonctionner ce code?
J'ai aussi essayé ceci:
def spitAt[A <: SpittableAnimal[A]](a: A): A = a.withMoreAnger
Mais des arguments de type inférées ne sont pas conformes à la méthode des limites des paramètres de type de spitAt qui est clair pour moi, puisque l'argument de type SELF
des éléments animals
sont au moins délimité par _ >: Cat with Dog <: Quadruped[_]
qui ne sont pas conformes avec a.SELF
, A
au-dessus dans spitAt
ou même A
le spitAt
ci-dessous:
def spitAt[A <: SpittableAnimal[S], S <: A](a: A): A = a.withMoreAnger
Alors, quelle est la bonne signature du spitAt
méthode pour faire fonctionner les lignes for
-loop?
Il se peut que des annotations de variance (+SELF
) du paramètre SELF soient utiles, mais je ne sais pas comment.
Désolé, mais je ne peux pas compiler votre code à l'aide scala 2.9.3: 'angryAnimals' ligne:' aucun paramètre de type pour la méthode spitAt: (spittee: ExcitableAnimal [T]) T existe pour qu'il puisse être appliqué aux arguments (Quadruped [_>: Cat avec Dog <: Quadruped [_>: Chat avec Dog <: ScalaObject] avec ScalaObject] avec ScalaObject) --- parce que --- le type d'expression de l'argument n'est pas compatible avec le type de paramètre formel; trouvé: Quadrupède [_>: Chat avec chien <: Quadrupède [_>: Chat avec chien <: ScalaObject] avec ScalaObject] avec ScalaObject requis: ExcitableAnimal [? 0T] 'Quelques conseils pour moi? –