これは、内部DSLの実装中に直面している問題を再現しようとするコードスニペットです。
object testObj {
implicit def foo1[T <% Function1[Int, Int]](fun: T): String = "foo1"
implicit def foo2[T <% Function2[Int, Int, Int]](fun: T): String = "foo2"
def test(arg: String): Unit = {}
test((x:Int) => 5) //Ambiguous implicit conversion error
test((x:Int, y:Int) => 5) //Ambiguous implicit conversion error
}
表示されている場所で、あいまいな暗黙の変換エラーが発生しています。
<console>:21: error: type mismatch;
found : Int => Int
required: String
Note that implicit conversions are not applicable because they are ambiguous:
both method foo1 in object testObj of type [T](fun: T)(implicit evidence$1: T => (Int => Int))String
and method foo2 in object testObj of type [T](fun: T)(implicit evidence$2: T => ((Int, Int) => Int))String
are possible conversion functions from Int => Int to String
test((x:Int) => 5) //Ambiguous implicit conversion error
^
ただし、暗黙の1つにコメントを付けても、問題は解決しません。最後に暗黙をチェーンしたいので、ビュー境界を使用しています。上記のコードスニペットには、暗黙的なチェーンが含まれていないことに注意してください。
foo1
暗黙の変換は最初のtest
アプリケーションに適用できるのに対し、foo2
暗黙の変換は2番目のアプリケーションに適用できると期待していましたtest
。test
両方の暗黙が両方の関数適用にどのように適用できるかわかりません。なぜこれが起こっているのですか、そしてこれをどのように機能させるのですか?
編集:ビュー境界を使用しない場合、以下に示すように正常に機能します。しかし、投稿で説明されている方法で暗黙をチェーンしたいので、ビュー境界を使用したいと思います。Scalaで暗黙をチェーンするには どうすればよいですか?。
implicit def foo1(fun: Function1[Int, Int]): String = "foo1"
implicit def foo2(fun: Function2[Int, Int, Int]): String = "foo2"
def test(arg: String): Unit = {}
test((x:Int) => 5) //No error
test((x:Int, y:Int) => 5) //No error