J'ai le code suivant définissant une classe de type.Typeclasses et sous-types
trait Foo[T] {
def toFoo(x: T): String
}
trait Foos {
def toFoo[T](f: T => String): Foo[T] = new Foo[T] {
def toFoo(x: T): String = f(x)
}
}
object Foo extends Foos {
def toFoo[A: Foo](a: A) = implicitly[Foo[A]].toFoo(a)
implicit def AToFoo: Foo[A] = toFoo { c =>
"A"
}
implicit def BToFoo[T]: Foo[B] = toFoo { c =>
"B"
}
implicit def ListToFoo[T: Foo]: Foo[List[T]] = toFoo { c =>
c.map(toFoo(_)).
}
}
class A
class B extends A
Maintenant, si je fais si je toFoo(List(new A, new B)
je reçois List("A", "A")
au lieu de List("A", "B")
. Comment puis-je m'assurer que la méthode BtoFoo
est utilisée plutôt que AToFoo
pour les classes de type B
?
Quel type attendez-vous de List (new A, new B) '? –
Je m'attends à 'List (new A, new B)' avoir le type 'List [A]' – Stephan
dans ce cas, quand vous mappez 'toFoo' sur la' List [A] ', il commence apparemment implicitement par [Foo [A]] 'et obtient la définition implicite de' AToFoo', et l'utilise pour chaque élément. Les classes de type sont conçues pour une diffusion orientée type, et non pour une diffusion orientée valeur, de sorte qu'elles ne jouent pas toujours bien avec le sous-typage. –