How does the indferencer type on reduceLeft work?

In addition to my other question about reduceLeftsignature reduceLefton Seqthere is

def reduceLeft [B >: A] (f: (B, A) ⇒ B): B 

and we can call it expressions such as

List(1,2,3,4) reduceLeft (_ + _)

This example Ais Int, therefore, reduceLeftexpects a Function2[B >: Int, Int, B]. Regardless of how reduceLeft works (which doesn't matter), how does the inferencer type know, what Bdoes the method +have when it can be of type Any?

+3
source share
2 answers

, 6.26.4 " " spec , . . , ( Any) ( ) ( Int).

, reduceLeft.

, , :

scala> List(1,2).reduceLeft[Any](_.toString + _)
res26: Any = 12

inferencer:

scala> List(1,2).reduceLeft(_.toString + _)
<console>:8: error: type mismatch;
 found   : java.lang.String
 required: Int
              List(1,2).reduceLeft(_.toString + _)

, , , :

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.

+4

B > : X X, B, B = X.

, B, . , , , , B X. .

class Y {
  def bar(y:Y) = this
}
case class X( i: Int ) extends Y {
  def foo(x:X)=X(i+x.i)
}
val t = new Y bar X(7)
val t2 = X(8) bar X(7)
val res = List(X(1),X(2),X(3)) reduceLeft { _ foo _ }
val res2 = List(X(1),X(2),X(3)) reduceLeft { _ bar _ } // will not compile
+1

All Articles