このような単純なクラスがあるとします
abstract class Foo {
implicit val impInt: Int = 42
def f[A]()(implicit a: A): A
val f2: Int = f()
}
val を宣言するとき、コンパイラは、関数の暗黙的なパラメーターの型が結果の型と同じであり、結果の型が value の型と一致する必要があるため、 であるとf2推測できます。fIntf2Int
ただし、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 であるため)。IntIntf2Int
implicit a: AOrdering 暗黙パラメーターのみを削除して残すと、エラーは残りますが、次のようになることに注意してください。
オブジェクト Ordering のメソッド Tuple9 で始まる型 Ordering[A] の暗黙的な展開の発散。
再び、型パラメーターを追加して、それがval f2: Int = f[Int]()役立つようにします。
どうしたの?コンパイラは、パラメーターが である必要があると推論できるのに、そのパラメーターAが である必要があると推論できないのはなぜですか?IntOrdering[A]Ordering[Int]