Проблема здесь в том, что вы передаете 5 как неявный параметр.
Теперь, когда я на компьютере, есть несколько исправлений:
def print[T <% Number](value:T) {}
Вы называете это функцией , но это метод .
def print2[T <% Number]: T => Unit = value => { }
Опять же, вы называете это функцией.На самом деле, это метод , который возвращает функцию.Метод получает один параметр типа T
и один неявный параметр.
print2(5)
Итак, здесь вы вызываете метод print2
, передавая 5
в качестве его неявного параметра.Тип T
еще не был выведен, потому что он сначала пытается согласовать 5
с ожидаемым типом T => Number
.Тем не менее, поскольку 5
не соответствует Function1[T, Number]
, происходит сбой, даже не выводя T
.
Существует множество способов вызова print2
.Например:
print2(implicitly[Int => Number])
print2[Int]
(print2: Int => Unit)
val f: Int => Unit = print2
Однако, чтобы вызвать функцию, возвращаемую print2
, вы должны избегать того, чтобы (5)
выглядел как неявный параметр для метода print2
.На самом деле есть только один приведенный выше случай, который требует чего-то другого:
print2(implicitly[Int => Number])(5)
print2[Int].apply(5)
(print2: Int => Unit)(5)
val f: Int => Unit = print2; f(5)
Теперь большинство этих примеров имеют явные, а не предполагаемые параметры типа.Давайте рассмотрим, что произойдет в его отсутствие:
print2.apply(5)
Поскольку ни один параметр не был передан в print2
, он выбирает наиболее конкретный тип, который соответствует границам T
.Поскольку T
не имеет границ, выбирается Nothing
.Затем он пытается найти неявное Nothing => Unit
.Поскольку такого неявного не существует, происходит сбой.
Параметр функции, который будет возвращен print2
, никогда не рассматривается для облегчения вывода типа.