Rozważmy następujący kod:niejawny rozdzielczości parametr dla wyższych typów kinded
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]) //???
}
}
To działa, ale muszę wpisać Niektórzy (42), a opcja [Int], inny niejawny obiekt OptionBar nie będzie rozwiązany (ponieważ oczekuje się paska [Część]). Czy istnieje sposób na uniknięcie jawnego wpisywania, tak aby uzyskać niejawny obiekt OptionBar w teście, nawet jeśli test jest podawany z parametrem Some lub None?
[Wyjaśnienie]
- użyłem opcji tutaj tylko jako przykład, powinien także działać, jeśli mam
Bar
dla klasy abstrakcyjnej itp - Roztwór powinien także działać, gdy inne, niezwiązane bary w zakresie, powiedzmy
implicit object listBar extends Bar[list]
[Aktualizacja]
wydaje się, że co baru parametru kontrawariantny robi t podstęp:
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))
}
}
Oczywiście jest to poważne ograniczenie możliwości w Bar, więc nadal mam nadzieję na lepszą odpowiedź.
Dlaczego kontrawariancja jest poważnym ograniczeniem? Bez użycia go, wtedy Bar jest niezmienny. Jeśli próbujesz użyć Bar jako klasy dla typów o wyższych typach, to kontrawariancja wydaje się pasować do mojego umysłu. To oczywiście, dopóki nie chcesz inaczej traktować podklas. Jednak w takim przypadku nadal masz inne sztuczki, takie jak ukryte rozdzielczości "priorytety" – jsuereth
@ Jos: Weź pod uwagę coś takiego jak 'cecha Bar [Q [_]] {def zero [T]: Q [T]}', zwracając Brak i Zero w moich przykładach. Ale nie mogę mieć takiej metody w Bar, jeśli zdefiniuję Q jako przeciwieństwo. Jeśli wiesz, jak rozwiązać ten problem, proszę dać mi znać ... – Landei
Ponadto, dla naturalnie sprzecznych klas typu, takich jak "Równe [T]", wyszukiwanie niejawne będzie faworyzować "Równe [Zwierzę]" nad "Równe [Pies] ': http://www.scala-lang.org/node/4626. Dziedziczenie i klasy typów są naprawdę trudne do połączenia razem. – retronym