Я думаю, что раздел 6.26.4 Local Type Inference в spec как бы объясняет, что происходит. Компилятор будет искать оптимальный тип. Когда параметр типа контравариантен, выбранный тип будет максимальным (в данном случае Any), а в противном случае (инвариантным или ковариантным) минимальным (в данном случае Int).
Есть пара примеров, которые я не могу связать с reduceLeft
.
Я заметил, что вывод, похоже, происходит до того, как я посмотрю на переданную анонимную функцию:
scala> List(1,2).reduceLeft[Any](_.toString + _)
res26: Any = 12
Но если я не помогу механизму вывода типов:
scala> List(1,2).reduceLeft(_.toString + _)
<console>:8: error: type mismatch;
found : java.lang.String
required: Int
List(1,2).reduceLeft(_.toString + _)
Edit, я ошибаюсь, учитывается анонимная функция, это работает:
List(1,2).reduceLeft((_:Any).toString + (_:Any).toString)
Есть опция компилятора -Ytyper-debug
, с которой вы можете работать:
List(1,2).reduceLeft(_+_)
Он покажет вам, что каким-то образом компилятор предполагает, что ожидаемым типом анонимной функции является (Int, Int) => Int
, затем он переходит к проверке _ + _
на соответствие ему и преуспевает, а затем выводит B
как Int
. Фрагмент здесь:
typed immutable.this.List.apply[Int](1, 2).reduceLeft: [B >: Int](f: (B, Int) => B)B
adapted immutable.this.List.apply[Int](1, 2).reduceLeft: [B >: Int](f: (B, Int) => B)B to ?, undetparams=type B
typing ((x$1, x$2) => x$1.$plus(x$2)): pt = (Int, Int) => Int: undetparams=,
// some time later
typed ((x$1: Int, x$2: Int) => x$1.+(x$2)): (Int, Int) => Int
adapted ((x$1: Int, x$2: Int) => x$1.+(x$2)): (Int, Int) => Int to (Int, Int) => Int,
typed immutable.this.List.apply[Int](1, 2).reduceLeft[Int](((x$1: Int, x$2: Int) => x$1.+(x$2))): Int
Я не знаю, почему при отсутствии описания типа предполагается, что анонимная функция равна (Int, Int) => Int
.
person
huynhjl
schedule
03.12.2011