Неявные параметры и универсальные типы
Я пытаюсь понять поведение компилятора в этой ситуации
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 => A
s. Компилятор ищет какую-то неявную функцию String => T
за foo
, но он не уверен, какой из них, и у вас есть несколько по объему. bar
не будет иметь приоритет, потому что вы не указали конкретный String => T
это ищет.
Это будет работать:
def foo[T](implicit x: (String => T)): T = ???
implicit val bar = (x: String) => x.toInt
foo[Int]