1

この状況でのコンパイラの動作を理解しようとしています

object ImplicitTest extends App {

  def foo[T](implicit x: (String => T)): T = ???

  implicit val bar = (x: String) => x.toInt

  foo
}

上記のコードはコンパイルされず、次のエラーが発生します。

あいまいな暗黙の値: 型 [A] のオブジェクト Predef のメソッド $conforms ⇒ <:<[A,A] と、型 ⇒ String ⇒ Int のオブジェクト ImplicitTest の値 bar の両方が期待される型 String ⇒ T に一致します。

エラーは、暗黙の値が Predef で定義された別の暗黙の値と競合していることを示しているため、これに基づいて、既知の型から未知の (ジェネリック) 型に値を変換する関数に暗黙のパラメーターを宣言する方法がないようです。

これは、コンパイラの技術的な制限によるものですか、それとも動作するはずの方法であり、私が認識していないいくつかの制約に違反していますか?

4

1 に答える 1

2

foo呼び出すときに型パラメーターを提供していないため (次の理由により、それを推論する方法は他にありません)、コンパイラーは正しいものと正しい暗黙のものを見つけるのに苦労しています。

bar: String => Intスコープ内に暗黙的がありますが、両方が拡張され、暗黙的 s を作成するとのインスタンスを作成する暗黙的あります。コンパイラは のいくつかの暗黙的な関数を探していますが、どれがどれかわからず、スコープ内に複数あります。探している特定のものを指定していないため、優先されません。Predef=:=<:<A => BString => AString => TfoobarString => T

これはうまくいきます:

def foo[T](implicit x: (String => T)): T = ???

implicit val bar = (x: String) => x.toInt

foo[Int]
于 2015-09-03T02:52:37.887 に答える