このような単純なクラスがあるとします
abstract class Foo {
implicit val impInt: Int = 42
def f[A]()(implicit a: A): A
val f2: Int = f()
}
val を宣言するとき、コンパイラは、関数の暗黙的なパラメーターの型が結果の型と同じであり、結果の型が value の型と一致する必要があるため、 であるとf2
推測できます。f
Int
f2
Int
ただし、Ordering[A]
ミックスに投入すると:
def f[A]()(implicit a: A, m: Ordering[A]): A
val f2: Int = f()
このコンパイル エラーが発生します。
あいまいな暗黙の値: 型 => scala.collection.generic.CanBuildFrom[String,Char,String] のオブジェクト Predef の値 StringCanBuildFrom と型 [A]=> <:<[A,A] のオブジェクト Predef のメソッド $conforms の両方予想されるタイプ A に一致
を呼び出すときに型情報を追加すると、次のf()
ようにコンパイルされます。
val f2: Int = f[Int]()
最初に、暗黙の順序付けのケースに遭遇しました。これは、Scala が左から右に推論することに関係していると思いました。最初に戻り値の型を一致させてから、 の (暗黙の) パラメータ型を推測することはできないと思いましたf
。しかし、暗黙の順序付けなしでケースを試してみたところ、それが機能することがわかりました-戻り値の型は an でなければならないため、f
によってパラメーター化する必要があると推測されました( is an であるため)。Int
Int
f2
Int
implicit a: A
Ordering 暗黙パラメーターのみを削除して残すと、エラーは残りますが、次のようになることに注意してください。
オブジェクト Ordering のメソッド Tuple9 で始まる型 Ordering[A] の暗黙的な展開の発散。
再び、型パラメーターを追加して、それがval f2: Int = f[Int]()
役立つようにします。
どうしたの?コンパイラは、パラメーターが である必要があると推論できるのに、そのパラメーターA
が である必要があると推論できないのはなぜですか?Int
Ordering[A]
Ordering[Int]