Ответ 1
См. раздел 8.5 справочника Scala (http://www.scala-lang.org/files/archive/nightly/pdfs/ScalaReference.pdf). Выражение { case (a, b) => a + b }
интерпретируется по-разному на основе ожидаемого типа. В вашем определении f1
он создал PartialFunction[(Int, Int), Int]
, который был добавлен в Function1[(Int, Int), Int]
, т.е. ((Int, Int)) => Int
, тогда как в определении f2
он создал Function2[Int, Int, Int]
, т.е. (Int, Int) => Int
.
Эти две интерпретации относятся к двум ситуациям, в которых вы обычно используете случай в анонимной функции.
Один из них предназначен для написания анонимных функций, которые принимают кортежи и работают с их компонентами, как и с f1
. Примером может служить функция, которую вы передаете методу foreach
или map
на map
, например. Map(1 -> 2, 3 -> 4) map { case (k, v) => k + v }
.
Вторая - для написания анонимной функции, которая делает match
единственным параметром. Ваш f2
делает это, но не каким-либо полезным способом. Примером может служить анонимная функция, переданная в collect
, например. List(1, -2, 3) collect { case x if x > 0 => -x }
.
Обратите внимание, что эти два могут быть объединены, то есть функции, подобные f1
, могут также выполнять сложное сопоставление. Например, Map(1 -> 2, 3 -> 4) collect { case (k, v) if k < 2 => v }
.
Изменить: res2
работает из-за tupling. Если приложение не вводит проверку, компилятор будет пытаться обернуть аргументы в кортеже перед сбоем.
Но это испробовано только для приложений; это не общее преобразование, как вы обнаружили. Он не будет пытаться обновить значение Function2[A, B, C]
до Function1[(A, B), C]
.