什么是发散隐式展开误差?
在尝试找到另一个问题的解决方案时( [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
^
While trying to find a solution to another question ([1]) I came across a diverging implicit expansion error. I'm looking for an explanation about what this means
Here's the use case:
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
^
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您在 scala 中运行此命令并传递
-Xlog-implicits
参数,您将获得更多信息:这主要是猜测,但似乎有一定道理。我将尝试进一步调查:
这似乎表明这里正在考虑三个隐式含义。最终,
sorted
的签名要求它找到Ordering[T]
类型的内容。所以它试图构造你的隐式函数ordering
。首先,它尝试通过查找类型(T) => 的隐式来填充
,它在 Predef 中搜索 - 这看起来像是找错了树。然后它试图找到一个隐式的conv
。 Ordered[T](Ordered[T]) =>; Ordered[Ordered[T]]
在同一位置,因为by
采用Ordering[S]
类型的隐式参数,其中S 凭借
conv
是Ordered[T]
。所以它无法构造ordering
。然后它尝试在 math.Ordering 中使用
ordering
,但这也不合适。然而,我认为这就是给出有点令人困惑的“分歧隐含”信息的原因。问题不在于它们存在分歧,而在于范围内没有合适的路径,而是因为有两条路可走,这一事实令人困惑。如果尝试在没有隐式有序函数的情况下定义 def foo[T <% Ordered[T]](s : Seq[T]) = s.sorted ,那么它会失败,只显示一条不错的消息说找不到合适的隐式。If you run this in scala with the
-Xlog-implicits
argument passed, you get more information:This is mostly speculation, but would seem to make some sense. I will try to investigate further:
This seems to suggest that there are three implicits that are being considered here. Ultimately, the signature of
sorted
requires it to find something of typeOrdering[T]
. So it's trying to construct your implicit functionordering
. Firstly, it's trying to fill inconv
by finding an implicit of type(T) => Ordered[T]
, where it's searching in Predef - which seems like barking up the wrong tree. It's then trying to find an implicit for(Ordered[T]) => Ordered[Ordered[T]]
in the same place, sinceby
takes an implicit parameter of typeOrdering[S]
, whereS
isOrdered[T]
by virtue ofconv
. So it can't constructordering
.It then tries to use
ordering
in math.Ordering, but this also doesn't fit. However, I think this is what's giving the somewhat confusing 'diverging implicits' message. The problem isn't that they're diverging, it's that there isn't a suitable one in scope, but it's being confused by the fact that there are two paths to go down. If one tries to definedef foo[T <% Ordered[T]](s : Seq[T]) = s.sorted
without the implicit ordered function, then it fails with just a nice message saying that it can't find a suitable implicit.