2012-07-29 90 views
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 
         ^

但是,评论其中一个含义并不能解决问题。我最终使用视图边界,因为我想链接这些含义。请注意,上面给出的代码片段不涉及隐式链接。

我期待的是foo1隐式转换将是适用于第一test应用而foo2隐式转换将是适用于第二test应用。 我不明白这两个implicits如何适用于test函数应用程序。为什么会发生这种情况,以及如何使这项工作?

编辑: 如果我不使用视图边界,它可以正常工作,如下所示。但是我想要使用视图边界,因为我想按照How can I chain implicits in Scala?后面的解释方式链接implicits。

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 
+0

我不明白你想达到什么目的。您能否详细说明如何以明确的方式解释代码? – sschaef 2012-07-29 09:56:36

+0

我知道很难理解代码在做什么......我已经简化了它太多以至于无法使用它......但是完整的代码涉及太多的依赖关系,我很难在这里提到它。我编辑过这个帖子,其中包含一个没有视图边界的例子。但是我想使用视图边界的原因是按照编辑的解释来链接implicits。 – dips 2012-07-29 11:43:35

+0

你想要链接什么?你想同时调用两个implicits吗?当你用函数调用'test'时,应该输出什么(或者应该调用哪个更好)? – sschaef 2012-07-29 11:50:36

回答

0

恐怕这是行不通的。视图边界在解决隐含时只是没有考虑到,因此你不能链接暗示。这是设计,因为这样的链接可能会创建一些非常不可读的代码。我看到的唯一选择是为每个可能的转换链创建一个新的隐式转换。

+0

这篇文章[如何在我的链中的implicits-scala](http://stackoverflow.com/questions/5332801/how-can-i-chain-implicits-in-scala)让我相信,在解决含义时要考虑视图边界。 – dips 2012-07-29 11:36:20