Xét đoạn mã sau:độ phân giải thông số ngầm với nhiều loại kinded cao
object foo {
trait Bar[Q[_]]
implicit object OptionBar extends Bar[Option]
def test[T, C[_]](c: C[T])(implicit bar: Bar[C]) =()
def main(args: Array[String]) {
test(Some(42): Option[Int]) //???
}
}
này hoạt động, nhưng tôi cần phải gõ một số (42) theo Option [Int], nếu không đối tượng OptionBar ngầm sẽ không được đã giải quyết (vì một thanh [Some] được mong đợi thay thế). Có cách nào để tránh việc gõ rõ ràng, để tôi có được đối tượng OptionBar tiềm ẩn trong thử nghiệm ngay cả khi tôi thử nghiệm nguồn cấp dữ liệu với một số hoặc không?
[Làm rõ]
- tôi đã sử dụng lựa chọn ở đây cũng giống như ví dụ, nó cũng nên làm việc nếu tôi có một
Bar
cho một lớp trừu tượng, vv - Giải pháp này cũng nên làm việc khi khác, không liên quan Bars là trong phạm vi, nói
implicit object listBar extends Bar[list]
[cập nhật]
dường như làm contravariant tham số Bar làm t anh ta lừa:
object foo {
trait Bar[-Q[_]] //<---------------
implicit object OptionBar extends Bar[Option]
implicit object ListBar extends Bar[List]
def test[T, C[_]](c: C[T])(implicit bar: Bar[C]) =()
def main(args:Array[String]) {
test(Some(42))
}
}
Nhưng tất nhiên đây là một hạn chế nghiêm trọng về khả năng trong Bar, vì vậy tôi vẫn hy vọng có câu trả lời tốt hơn.
Tại sao contravariance là một hạn chế nghiêm trọng? Không sử dụng nó, thì Bar là bất biến. Nếu bạn đang cố gắng sử dụng Bar như là một loại lớp chống lại các loại cao hơn mà contravariance dường như phù hợp trong tâm trí của tôi. Đó là tất nhiên cho đến khi bạn muốn điều trị các lớp con khác nhau. Tuy nhiên, trong trường hợp đó, bạn vẫn có các thủ thuật khác, như độ phân giải ngầm "ưu tiên" – jsuereth
@Josh: Hãy xem xét một cái gì đó như 'trait Bar [Q [_]] {def zero [T]: Q [T]}', không trả lại None và Nil trong ví dụ của tôi. Nhưng tôi không thể có một phương pháp như vậy trong Bar, nếu tôi định nghĩa Q là contravariant. Khi bạn biết cách giải quyết điều này, hãy cho tôi biết ... – Landei
Ngoài ra, đối với một loại kiểu tự nhiên contravariant, chẳng hạn như 'Equal [T]', tìm kiếm ngầm sẽ ưu tiên 'Equal [Animal]' trên 'Equal [Dog] ': http://www.scala-lang.org/node/4626. Các lớp thừa kế và kiểu lớp thực sự phức tạp để liên kết với nhau. – retronym