Рассмотрим следующий код:
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]) //???
}
}
Это работает, но мне нужно ввести Some (42) как Option [Int], иначе неявный объект OptionBar не будет разрешен (потому что вместо этого ожидается Bar [Some]). Есть ли способ избежать явной типизации, чтобы я получал неявный объект OptionBar в тесте, даже если я загружаю тест с помощью Some или None?
[Разъяснение]
- Я использовал здесь Option как пример, он также должен работать, если у меня есть
Bar
для абстрактного класса и т. Д. - Решение также должно работать, когда в области видимости находятся другие, несвязанные панели, например
implicit object listBar extends Bar[list]
[Обновлять]
Похоже, что создание контравариантного параметра Бар помогает:
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))
}
}
Но, конечно, это серьезное ограничение возможностей в Bar, поэтому я все еще надеюсь на лучший ответ.
trait Bar[Q[_]] { def zero[T]:Q[T] }
, возвращая None и Nil в моих примерах. Но у меня не может быть такого метода в Bar, если я определю Q как контравариантный. Когда вы узнаете, как это решить, дайте мне знать ... - person Landei   schedule 30.09.2010Equal[T]
, неявный поиск будет отдавать предпочтениеEqual[Animal]
надEqual[Dog]
: scala -lang.org/node/4626. Классы наследования и типов действительно сложно соединить вместе. - person retronym   schedule 30.09.2010