Je pense que la section 6.26.4 Inférence de type local du genre de spec explique ce qui se passe. Le compilateur recherchera un type optimal. Lorsque le paramètre type est contravariant, le type choisi sera maximal (dans ce cas Any) et sinon (invariant ou covariant) minimal (dans ce cas Int).
Il y a quelques exemples que je ne peux pas vraiment rapporter à reduceLeft
.
Ce que j'ai remarqué est la conclusion semble se produire avant de regarder la fonction anonyme passé:
scala> List(1,2).reduceLeft[Any](_.toString + _)
res26: Any = 12
Mais si je n'aiderai pas le type inferencer:
scala> List(1,2).reduceLeft(_.toString + _)
<console>:8: error: type mismatch;
found : java.lang.String
required: Int
List(1,2).reduceLeft(_.toString + _)
Modifier , Je me trompe la fonction anonyme est prise en compte, cela fonctionne:
List(1,2).reduceLeft((_:Any).toString + (_:Any).toString)
Il y a un compilateur l'option -Ytyper-debug
que vous pouvez exécuter sur:
List(1,2).reduceLeft(_+_)
Il vous montrera que en quelque sorte le compilateur suppose que le type attendu de la fonction anonyme est (Int, Int) => Int
, il procède de vérifier la _ + _
contre et réussit, puis déduit B
comme Int
. Snippet ici:
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
Je ne sais pas pourquoi, en l'absence de type ascription la fonction anonyme est supposée être (Int, Int) => Int
.