Ответ 1
Ну, есть некоторые угловые случаи вроде: рекурсивный метод должен быть явно типизирован, но обычно правило имеет следующий вид: типы должны откуда-то появляться.
Либо они поступают из ссылочной части:
val function: (Int, Int) => Int = _ + _
или из части объекта:
val function = (x: Int, y: Int) => x + y
не имеет большого значения. (в Scala!)
Я знаю, что вы задаете вопрос о функциях, но вот пример, иллюстрирующий вывод типа Scala:
// no inference
val x: HashMap[String, Int] = new HashMap[String, Int]()
val x: HashMap[String, Int] = new HashMap[String, Int]
// object inference
val x: HashMap[String, Int] = new HashMap()
val x: HashMap[String, Int] = new HashMap
val x: HashMap[String, Int] = HashMap() // factory invocation
// reference inference
val x = new HashMap[String, Int]()
val x = new HashMap[String, Int]
val x = HashMap[String, Int]() // factory invocation
// full inference
val x = HashMap("dog" -> 3)
EDIT В соответствии с запросом я добавляю случай функции более высокого порядка.
def higherOrderFunction(firstClassFunction: (Int, Int) => Int) = ...
можно вызвать так:
higherOrderFunction(_ + _) // the type of the firstClassFunction is omitted
Но это не особый случай. Тип ссылки явно упоминается. Следующий пример иллюстрирует аналогичный пример.
var function: (Int, Int) => Int = null
function = _ + _
Это примерно эквивалентно случаю функции более высокого порядка.