Скажем, у нас есть две следующие черты:
trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar
И неявное преобразование из второго в первое:
implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
Мы создаем Bar
и список целых чисел:
val bar = new Bar {}
val stuff = List(1, 2, 3)
Теперь я ожидаю, что следующее будет работать:
bar howMany stuff
Но это не так:
scala> bar howMany stuff
<console>:13: error: type mismatch;
found : List[Int]
required: List[A]
bar howMany stuff
^
Итак, переходим к спецификацию, которая имеет это сказать (выделение жирным шрифтом принадлежит мне):
Представления применяются в трех ситуациях.
[Здесь не актуально.]
В выборе e.m с e типа T, , если селектор m не обозначает член T. В этом случае выполняется поиск вида v применим к e и результат которого содержит член с именем m. поиск продолжается, как в случае неявных параметров, где неявная область охвата - таковая из T. Если такое представление найдено, выбор e.m преобразуется в v (e).m.
В выборе em (args) с e типа T, , если селектор m обозначает некоторый член T, но ни один из этих членов не применим к аргументам args, В этом случае выполняется поиск вида v которая применима к e и результат которой содержит метод m который применим к args. Поиск продолжается, как в случае неявные параметры, где неявная область - таковая из T. Если такой взгляд найден, выбор e.m преобразуется в v (е).m(арг).
Итак, мы пытаемся сделать следующее, думая, что это должно быть слишком абсурдно работать:
trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar { def howMany = throw new Exception("I don't do anything!") }
implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
val bar = new Bar {}
val stuff = List(1, 2, 3)
Но он (как на 2.9.2, так и на 2.10.0-RC2, по крайней мере):
scala> bar howMany stuff
res0: Int = 3
Это приводит к некоторому действительно странному поведению, например, в этом обходном пути для этой проблемы.
У меня есть три (тесно связанных) вопроса:
- Есть ли простой способ (т.е. тот, который не включает добавление поддельных методов с соответствующим именем), чтобы правильно применить представление в исходном случае выше?
- Может ли кто-нибудь предоставить чтение спецификации, которая учитывает это поведение?
- Предполагая, что это предполагаемое поведение, вообще ли оно имеет смысл?
Я также ценю любые ссылки на предыдущие обсуждения этой проблемы - мне не очень повезло с Google.