Неявные параметры и универсальные типы

Я пытаюсь понять поведение компилятора в этой ситуации

object ImplicitTest extends App {

  def foo[T](implicit x: (String => T)): T = ???

  implicit val bar = (x: String) => x.toInt

  foo
}

приведенный выше код не компилируется и выдает следующую ошибку:

неоднозначные неявные значения: оба метода $ соответствуют объекту Predef типа [A]⇒<: <[A, A] и строке значений в объекте ImplicitTest типа ⇒ String ⇒ Int соответствуют ожидаемому типу String ⇒ T

поскольку ошибка говорит, что мое неявное значение конфликтует с другим неявным значением, определенным в Predef... исходя из этого, кажется, что нет способа объявить неявный параметр функции, преобразующей значение из известного типа в неизвестный (универсальный) тип.

Это из-за каких-то технических ограничений на компилятор или просто так, как он должен работать, и я нарушаю некоторые ограничения, о которых я не знаю?

1 ответ

Решение

Вы не предоставляете параметр типа для foo когда вы вызываете его (и нет другого способа сделать вывод по следующей причине), то у компилятора возникают проблемы с поиском правильного и правильного неявного.

У вас есть неявное bar: String => Int по объему, но у вас также есть последствия в Predef которые создают экземпляры =:= а также <:< которые оба расширяются A => Bи создать неявное String => As. Компилятор ищет какую-то неявную функцию String => T за foo, но он не уверен, какой из них, и у вас есть несколько по объему. bar не будет иметь приоритет, потому что вы не указали конкретный String => T это ищет.

Это будет работать:

def foo[T](implicit x: (String => T)): T = ???

implicit val bar = (x: String) => x.toInt

foo[Int]
Другие вопросы по тегам