Сообщение об ошибке указывает вам правильное направление: как метод , f
не является прямым эквивалентом значению типа Int => Int
, даже если они похожи.Чтобы передать его в качестве аргумента, f
необходимо преобразовать в значение, что часто, но не всегда, делается неявно.
Когда вы объявляете val g = f _
или используете A.bar(f _)
, вы явно конвертируете метод в значение.
Поскольку метод bar
перегружен, компилятор не уверен, в какой тип вы преобразуете f
(это Int => Int
или (Int,Int) => Int
?).Чтобы избежать какого-либо удивления, он просит вас явное преобразование.Вы также можете заставить его скомпилировать, используя A.bar(f: Int => Int)
, потому что это устраняет неоднозначность, явно выбрав одно из bar
определений.
Компилятор может попытаться рассуждать об этом, потому что вы передаете Int => Int
и неявный метод-> поднятие значения может произойти, только если вы хотите присвоить его bar(Int => Int)
, но в этом случае это просто не так.Для этого может быть техническая причина, например, компилятор не пытается объединить разрешения перегрузок и неявный подъем из-за комбинаторного взрыва.Я бы посчитал это небольшим ограничением компилятора, которое легко обойти, если быть более явным.Более подробное часто лучше!
Как указано в комментариях @slouc, более технические подробности по этому вопросу доступны здесь .