C'è qualche ragione per cui il tratto di Scala Ordering
non è controverso? Segue un esempio motivante.Scala: Order controvarianze
Supponiamo di voler eseguire un inserto ordinato. Io possa avere una funzione con la firma
def insert[A, B >: A](list: List[A], item: A)(implicit ord: Ordering[B]): List[A]
Qui, ho un Ordering
che accetta di super tipi di tipo A
. Immagino sia utile quando hai a che fare con case classes
. Per esempio:
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)
}
vorrei la mia funzione di inserimento al lavoro con i tipi List[CodeTree]
, List[Leaf]
o List[Fork]
. Tuttavia, poiché Ordering
non è controverso, è necessario definire implicito Orderings
per ogni case
.
Se io definisco
trait MyOrdering[-A] {
def compare(a: A, b: A): Int
}
tutto funziona come previsto.
C'è qualche altro modo per raggiungere il mio obiettivo?
EDIT:
mia soluzione attuale è quello di definire inserto come
def insert[A](list: List[A], item: A)(implicit ord: Ordering[A]): List[A]
che funziona bene quando si tratta di List[CodeTree]
. Ho anche definisco (ispirato dalla libreria scalaz):
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)
Sto definendo una funzione di fabbrica implicito per Ordering[A <: CodeTree]
istanze.
Sembra che si tratti di un problema tecnico relativo al tipo di inferenza che non riesce a trovare l'ordinamento più specifico. Vedi http://scala-programming-language.1934581.n4.nabble.com/Contravariant-Ordering-T-java-util-Comparator-and-uncheckedVariance-td1955224.html per i dettagli. – Impredicative
@Impredicative Ho modificato il post con una brutta soluzione. –