7

このような単純なクラスがあるとします

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]

4

1 に答える 1

1

以下のコードが機能するため、順序付けインスタンスが生成される方法に何か問題があるに違いありません。バグを報告します。

case object types {
  implicit def buh[X]: List[X] = List()
}
abstract class Foo {

  import types._

  def f[A]()(implicit l: List[A]): A
  val f2: Int = f()
}
于 2016-11-15T12:12:28.217 に答える