2011-12-03 45 views
3

はまたmy other questionreduceLeftSeqreduceLeftの署名がreduceLeftで型推論機能はどのように機能しますか?

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

であり、我々はこの例Aでは、このような

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

として表現でそれを呼び出すことができIntので、reduceLeftFunction2[B >: Int, Int, B]を期待します。 reduceLeftがどのように機能するか(関係はありません)に関係なく、タイプ推論はAnyのタイプである場合、B+メソッドを持つことをどのように知っていますか?

答えて

1

> Bの場合:XとコンパイラがXを知っているが、それをB解決することはできません単にそれだけでBの2つのオプションがあり、一つだけが知られているので、それはやや実用的であるB = X.

を前提としています。 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 
4

私はセクション6.26.4ローカル型推論specは一種の何が起こっているのか説明してだと思います。コンパイラは最適な型を探します。型パラメータが反変である場合、選択される型は最大(この場合はAny)であり、そうでなければ(不変または共変)最小(この場合Int)です。

実際にはreduceLeftには関連しない例がいくつかあります。私は通知が推論されたのは何

は、渡された匿名関数を見る前に発生するようです:

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

編集

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

をしかし、私はタイプinferencerを助けていない場合私は無名関数が考慮されている間違った、この作品:

List(1,2).reduceLeft((_:Any).toString + (_:Any).toString) 
それはそれに対して _ + _をチェックするために進んで、それは何らかの形でコンパイラは無名関数の期待されるタイプを想定していることを示します

List(1,2).reduceLeft(_+_) 

(Int, Int) => Intです:

あなたが上で実行することができますコンパイラ-Ytyper-debugオプションがあります成功し、次にBIntと推定します。ここスニペット:

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であると仮定される理由を私は知りません。

関連する問題