Хотя правда сложна , я собираюсь продолжить обсуждение, в котором применяется тот же принцип, но многое упрощается, чтобы вы могли видеть логику в языке.
В Scala отсутствует перегрузка в зависимости от типа возвращаемого значения. (Даже в сопоставлении с шаблоном, где «параметры» для шаблона совпадают с типом возврата из unapply
, что позволяет использовать тип возвращаемого значения для устранения перегрузки.)
Вы не перегружаете метод map
на основе типа возвращаемого значения - вы перегружаете его на основе возвращаемого типа функции, передаваемой в качестве параметра. Изменение типа возвращаемого значения изменяет тип возвращаемого значения параметра, поэтому вы по существу перегружены на основе разных типов параметров. Итак, логически говоря, у вас есть нечто эквивалентное следующей ситуации:
trait Seq[X]{
def map[Y](func: X => Y) : Seq[Y]
def map[Y,Z](func: X => Tuple2[Y,Z]) : Map[Y,Z]
}
Тип возвращаемого значения функции, передаваемой в map, определяет, какая версия вызывается.
Реальная реализация просто делает эту логику более общей и расширяемой для множества типов коллекций, которые есть в библиотеке Scala, и для множества других типов коллекций, которые еще не были написаны.