Có bất kỳ lý do nào tại sao đặc điểm của Scala là Ordering
không phải là contravariant? Một ví dụ thúc đẩy sau.Scala: Đặt hàng contravariance
Giả sử tôi muốn thực hiện chèn được sắp xếp. Tôi có thể có một chức năng với chữ ký
def insert[A, B >: A](list: List[A], item: A)(implicit ord: Ordering[B]): List[A]
Ở đây, tôi có một Ordering
mà chấp nhận loại siêu kiểu A
. Tôi tưởng tượng điều này rất hữu ích khi bạn đang giao dịch với case classes
. Ví dụ:
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)
}
tôi muốn chức năng chèn của tôi để làm việc với các loại List[CodeTree]
, List[Leaf]
hoặc List[Fork]
. Tuy nhiên, như Ordering
không phải là contravariant, tôi cần phải xác định tiềm ẩn Orderings
cho mỗi case
.
Nếu tôi xác định
trait MyOrdering[-A] {
def compare(a: A, b: A): Int
}
mọi thứ hoạt động như mong đợi.
Có cách nào khác để đạt được mục tiêu của tôi không?
EDIT:
giải pháp hiện tại của tôi là xác định chèn như
def insert[A](list: List[A], item: A)(implicit ord: Ordering[A]): List[A]
mà hoạt động tốt khi giao dịch với List[CodeTree]
. Tôi cũng xác định (lấy cảm hứng từ thư viện 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)
Tôi đang xác định hàm nhà máy ngầm cho Ordering[A <: CodeTree]
trường hợp.
Có vẻ như đó là một vấn đề kỹ thuật liên quan đến trình inferencer loại không tìm được thứ tự cụ thể nhất. Xem http://scala-programming-language.1934581.n4.nabble.com/Contravariant-Ordering-T-java-util-Comparator-and-uncheckedVariance-td1955224.html để biết chi tiết. – Impredicative
@Impredicative Tôi đã chỉnh sửa bài đăng bằng cách giải quyết khó chịu. –