Вывод типа не работает должным образом, так как подпись List#toSet
равна
def toSet[B >: A] => scala.collection.immutable.Set[B]
и компилятор должен будет вывести типы в двух местах вашего вызова. Альтернативой аннотированию параметра в вашей функции может быть вызов toSet
с явным аргументом типа:
xs.toSet[Int] map (_*2)
ОБНОВЛЕНИЕ :
Что касается вашего вопроса, почему компилятор может вывести его за два шага, давайте просто посмотрим, что происходит, когда вы печатаете строки одну за другой:
scala> val xs = List(1,2,3)
xs: List[Int] = List(1, 2, 3)
scala> val ys = xs.toSet
ys: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
Здесь компилятор выведет наиболее конкретный тип для ys
, который в данном случае равен Set[Int]
. Этот тип теперь известен, поэтому можно определить тип функции, переданной в map
.
Если вы указали все возможные параметры типа в вашем примере, вызов будет записан как:
xs.toSet[Int].map[Int,Set[Int]](_*2)
где параметр второго типа используется для указания типа возвращаемой коллекции (подробнее смотрите, как реализованы коллекции Scala). Это означает, что я даже недооценил количество типов, которые должен выводить компилятор.
В этом случае может показаться, что легко сделать вывод Int
, но в некоторых случаях это не так (учитывая другие особенности Scala, такие как неявные преобразования, синглтон-типы, черты в виде миксинов и т. Д.). Я не говорю, что это невозможно, просто компилятор Scala этого не делает.