Gibt es einen Grund, warum Scala Ordering
Merkmal nicht kontravariant ist? Ein motivierendes Beispiel folgt.Scala: Bestellung Kontravarianz
Angenommen, ich möchte eine geordnete Beilage durchführen. Ich kann mit der Unterschrift
def insert[A, B >: A](list: List[A], item: A)(implicit ord: Ordering[B]): List[A]
hier eine Funktion haben, ich habe ein Ordering
die A
Supertypen vom Typ akzeptiert. Ich denke, das ist nützlich, wenn Sie mit case classes
zu tun haben. Zum Beispiel:
abstract class CodeTree
case class Fork(left: CodeTree, right: CodeTree, chars: List[Char], weight: Int) extends CodeTree
case class Leaf(char: Char, weight: Int) extends CodeTree
def weight(tree: CodeTree): Int
def chars(tree: CodeTree): List[Char]
implicit object CodeTreeOrdering extends Ordering[CodeTree] {
def compare(a: CodeTree, b: CodeTree): Int = weight(a) compare weight(b)
}
würde ich meine Insert-Funktion will mit Typen List[CodeTree]
, List[Leaf]
oder List[Fork]
zu arbeiten. Da Ordering
jedoch nicht kontravariant ist, muss ich implizit Orderings
für jeden case
definieren.
Wenn ich definieren
trait MyOrdering[-A] {
def compare(a: A, b: A): Int
}
alles wie erwartet funktioniert.
Gibt es einen anderen Weg, um mein Ziel zu erreichen?
EDIT:
Meine aktuelle Lösung ist Einsatz als
def insert[A](list: List[A], item: A)(implicit ord: Ordering[A]): List[A]
zu definieren, die gut funktionieren, wenn sie mit List[CodeTree]
beschäftigen. Ich sehe auch (durch die scalaz Bibliothek inspiriert):
trait Contravariant[F[_]] {
def contramap[A, B](r: F[A], f: B => A): F[B]
}
implicit object OrderingContravariant extends Contravariant[Ordering] {
def contramap[A, B](r: Ordering[A], f: B => A) = r.on(f)
}
implicit def orderingCodeTree[A <: CodeTree]: Ordering[A] =
implicitly[Contravariant[Ordering]].contramap(CodeTreeOrdering, identity)
ich eine implizite Fabrik Funktion für Ordering[A <: CodeTree]
Instanzen bin definieren.
Sieht so aus, als wäre es ein technisches Problem, wenn der Typinterferenzer die spezifischste Reihenfolge nicht findet. Siehe http://scala-programming-language.1934581.n4.nabble.com/Contravariant-Ordering-T-java-util-Comparator-and-unchedVariance-td1955224.html für Details. – Impredicative
@Impredicative Ich habe den Beitrag mit einem fiesen Workaround bearbeitet. –