什么是分歧的隐式扩展错误?

时间:2011-02-03 08:39:43

标签: scala implicits

在尝试找到另一个问题([1])的解决方案时,我遇到了一个不同的隐式扩展错误。我正在寻找关于这意味着什么的解释

以下是用例:

scala> implicit def ordering[T](implicit conv: T => Ordered[T], res: Ordering[Ordered[T]]) = Ordering.by(conv)
ordering: [T](implicit conv: (T) => Ordered[T],implicit res: Ordering[Ordered[T]])scala.math.Ordering[T]

scala> def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
<console>:6: error: diverging implicit expansion for type Ordering[T]
starting with method ordering in object $iw
       def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
                                                ^

1 个答案:

答案 0 :(得分:21)

如果在传递-Xlog-implicits参数的scala中运行此命令,则可以获得更多信息:

  

scala.this.Prefed.conforms不是(T)=&gt;的有效隐含值。订购[T]因为:

     

类型不匹配:

     

发现:&lt;:&lt; [T,T]

     

要求:(T)=&gt;有序[T]

     

scala.this.predef.conforms不是(Ordered [T])=&gt;的有效隐含值。订购[订购[T]]因为:

     

类型不匹配:

     

发现:&lt;:&lt; [Ordered [T],Ordered [T]]

     

必需:(有序[T])=&gt;序[有序[T]]

     

math.this.Ordering.ordered不是Ordering [T]的有效隐含值,因为:

     

类型参数[T]不符合方法有序的类型参数边界[A&lt;:scala.math.Ordered [A]]

这主要是猜测,但似乎有道理。我会尝试进一步调查:

这似乎表明这里有三个含义。最终,sorted的签名要求它找到Ordering[T]类型的内容。所以它试图构造你的隐含函数ordering。首先,它试图通过找到类型conv的隐式来填充(T) => Ordered[T],它在Predef中进行搜索 - 这似乎是在咆哮错误的树。然后尝试在同一个地方找到隐含的(Ordered[T]) => Ordered[Ordered[T]],因为by采用Ordering[S]类型的隐式参数,其中SOrdered[T] conv。所以它无法构建ordering

然后尝试在math.Ordering中使用ordering,但这也不合适。但是,我认为这就是给出了一些令人困惑的“不一致的暗示”信息。问题不在于它们是分歧的,而是在范围内没有合适的问题,但是它有两条路可走的事实让人感到困惑。如果一个人试图在没有隐式有序函数的情况下定义def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted,那么它会失败,只有一条好消息说它无法找到合适的隐式函数。