scala 什么是发散的隐式扩展错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4883906/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:47:10  来源:igfitidea点击:

What is a diverging implicit expansion error?

scalaimplicits

提问by IttayD

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

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

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
                                                ^

采纳答案by Submonoid

If you run this in scala with the -Xlog-implicitsargument passed, you get more information:

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

scala.this.Prefed.conforms is not a valid implicit value for (T) => Ordered[T] because:

type mismatch:

found : <:<[T,T]

required: (T) => Ordered[T]

scala.this.predef.conforms is not a valid implicit value for (Ordered[T]) => Ordered[Ordered[T]] because:

type mismatch:

found : <:<[Ordered[T], Ordered[T]]

required : (Ordered[T]) => Ordered[Ordered[T]]

math.this.Ordering.ordered is not a valid implicit value for Ordering[T] because:

type arguments [T] do not conform to method ordered's type parameter bounds [A <: scala.math.Ordered[A]]

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]]

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 sortedrequires it to find something of type Ordering[T]. So it's trying to construct your implicit function ordering. Firstly, it's trying to fill in convby 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, since bytakes an implicit parameter of type Ordering[S], where Sis Ordered[T]by virtue of conv. So it can't construct ordering.

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

It then tries to use orderingin 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 define def foo[T <% Ordered[T]](s : Seq[T]) = s.sortedwithout the implicit ordered function, then it fails with just a nice message saying that it can't find a suitable implicit.

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