Почему Scala не может найти вторичное неявное значение в этом конкретном случае? - PullRequest
8 голосов
/ 04 февраля 2012

Мне трудно объяснить разницу в поведении между дополнительными неявными значениями, которые ищут либо первичное неявное значение, либо неявное преобразование.В частности, это работает:

trait Foo[A]
implicit def fooString: Foo[String] = null

implicit def value[A](implicit foo: Foo[A]) = 5

> implicitly[Int]
5

Но это не так:

implicit def conversion[A](x: Int)(implicit foo: Foo[A]) = new {
    def aMethod = 5
}

> 1.aMethod
could not find implicit value for parameter foo: test.Foo[A]

Варьирование:

  • Начинается ли поиск с implicitly илинеявное преобразование
  • является ли полиморфным искомое вторичное неявное значение
  • является ли полученное вторичное неявное значение полиморфным

Я получаю следующие результаты:

Conversion/value  Searching for  Supplied | Works?
----------------  -------------  -------- | ------
     conversion     poly          poly    |  yes
     conversion     poly          mono    |  **no**
     conversion     mono          poly    |  yes
     conversion     mono          mono    |  yes
     value          poly          poly    |  yes
     value          poly          mono    |  yes
     value          mono          poly    |  yes
     value          mono          mono    |  yes

Как видите, единственный случай, который не работает, - это когда поиск запускается неявным преобразованием, искомое значение является полиморфным, но предоставленное значение является мономорфным.

Есть литеоретическая причина, почему так должно быть, или это ошибка / ограничение Scala?

Ответы [ 2 ]

7 голосов
/ 04 февраля 2012

Вас укусила скалярная ошибка SI-3346 . В более общем случае см. Описание SI-4699 , особенно точка (1),

1) неявный поиск и поиск неявного преобразования по-разному обрабатывают неопределенные параметры типа

, который вы наблюдаете непосредственно, когда ваши случаи различают неявные значения и неявные преобразования.

Я обновил SI-3346, чтобы включить его в качестве дополнительного примера.

3 голосов
/ 04 февраля 2012

Измените подпись неявного преобразования следующим образом:

implicit def conversion[A](a: A)(implicit foo: Foo[A]) = new {

Затем вызовите aMethod для значения типа, для которого определено неявное значение, то есть с String :

scala> "foo".aMethod
res0: Int = 5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...