48

在尝试解决另一个问题([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
                                                ^
4

1 回答 1

23

如果您在-Xlog-implicits传递参数的情况下在 scala 中运行它,您将获得更多信息:

scala.this.Prefed.conforms 不是 (T) => Ordered[T] 的有效隐式值,因为:

类型不匹配:

找到:<:<[T,T]

必需:(T) => 有序[T]

scala.this.predef.conforms 不是 (Ordered[T]) => Ordered[Ordered[T]] 的有效隐式值,因为:

类型不匹配:

找到:<:<[有序[T],有序[T]]

必需:(Ordered[T]) => Ordered[Ordered[T]]

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

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

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

这似乎表明这里正在考虑三个隐含。最终, 的签名sorted要求它找到 type 的东西Ordering[T]。所以它试图构建你的隐式函数ordering。首先,它试图conv通过找到一个隐含的 type来填充(T) => Ordered[T],它在 Predef 中搜索 - 这似乎是在找错误的树。然后它试图(Ordered[T]) => Ordered[Ordered[T]]在同一个地方找到一个隐含的 for,因为by它需要一个 type 的隐式参数Ordering[S],其中SOrdered[T]凭借conv. 所以它不能构造ordering.

然后它尝试ordering在 math.Ordering 中使用,但这也不适合。然而,我认为这就是给出有点令人困惑的“发散隐含”信息的原因。问题不在于它们出现分歧,而在于范围内没有合适的范围,但它被两条路走下去的事实弄糊涂了。如果一个人试图在def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted没有隐式有序函数的情况下进行定义,那么它会失败,只显示一条很好的消息,说明它找不到合适的隐式函数。

于 2011-02-03T11:47:17.093 回答