3

これは、内部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番目のアプリケーションに適用できると期待していましたtesttest両方の暗黙が両方の関数適用にどのように適用できるかわかりません。なぜこれが起こっているのですか、そしてこれをどのように機能させるのですか?

編集:ビュー境界を使用しない場合、以下に示すように正常に機能します。しかし、投稿で説明されている方法で暗黙をチェーンしたいので、ビュー境界を使用したいと思います。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
4

1 に答える 1

0

これはうまくいかないのではないかと心配しています。暗黙を解決するときにビューの境界が考慮されないため、暗黙を連鎖することはできません。これは設計上の問題です。このような連鎖は、非常に判読できないコードを作成する可能性があるためです。私が見る唯一のオプションは、可能な変換チェーンごとに新しい暗黙的な変換を作成することです。

于 2012-07-29T07:51:04.707 に答える