gpt4 book ai didi

scala - "diverging implicit expansion"scalac 消息是什么意思?

转载 作者:行者123 更新时间:2023-12-03 20:00:58 25 4
gpt4 key购买 nike

我创建了一个小示例程序来尝试找出为什么没有编译更大的程序。

val o1: Ordered[Int] = 1
val o2: Ordered[Int] = 2
println(o1 < o2)

当我把它喂给 Scala 时,我得到:
Ordered.scala:3: error: diverging implicit expansion for type scala.math.Ordering[Ordered[Int]]
starting with method ordered in trait LowPriorityOrderingImplicits
println(o1 < o2)
^
one error found

使用“-explaintypes”并不能提供更多信息。但是,“-Xlog-implicits”给出了以下内容:
math.this.Ordering.comparatorToOrdering is not a valid implicit value for scala.math.Ordering[Ordered[Int]] because:
could not find implicit value for parameter cmp: java.util.Comparator[Ordered[Int]]
scala.this.Predef.conforms is not a valid implicit value for Ordered[Int] => java.lang.Comparable[Ordered[Int]] because:
type mismatch;
found : <:<[Ordered[Int],Ordered[Int]]
required: Ordered[Int] => java.lang.Comparable[Ordered[Int]]
/Users/steshaw/Projects/playground/scala/programming-in-scala/Ordered.scala:3: error: diverging implicit expansion for type scala.math.Ordering[Ordered[Int]]
starting with method ordered in trait LowPriorityOrderingImplicits
println(o1 < o2)
^
math.this.Ordering.comparatorToOrdering is not a valid implicit value for scala.math.Ordering[Ordered[Int]] because:
could not find implicit value for parameter cmp: java.util.Comparator[Ordered[Int]]
scala.this.Predef.conforms is not a valid implicit value for Ordered[Int] => java.lang.Comparable[Ordered[Int]] because:
type mismatch;
found : <:<[Ordered[Int],Ordered[Int]]
required: Ordered[Int] => java.lang.Comparable[Ordered[Int]]
one error found

但这对我没有帮助。想知道此消息的含义以及如何解决它?

[更新] 今天与 Scala 2.11.0 相同的代码除了第一条关于“发散隐式扩展”的错误消息外,还会产生第二条错误消息。第二条消息很有帮助。
$ scala Ordered.scala
Ordered.scala:3: error: diverging implicit expansion for type scala.math.Ordering[Ordered[Int]]
starting with method comparatorToOrdering in trait LowPriorityOrderingImplicits
println(o1 < o2)
^
/Users/steshaw/Projects/playground/scala/scalac-errors/Ordered.scala:3: error: type mismatch;
found : Ordered[Int]
required: Int
println(o1 < o2)
^
two errors found

最佳答案

很快:您的错误消息应该只是

error: type mismatch 
found: Ordering[Int]
required: Int.

原因很简单,在 Ordered[A] , 比较是用 A 做的, 不与其他排序
def <(that: A): Boolean

那应该是 o1 < 2 ,不是 o1 < o2 . (当然 1 < 2 也可以,但我希望你的代码只是其他东西的简化版本)

但是,在编译器报告这个简单的错误之前,如果必须搜索范围中的某些隐式是否可以解决问题。它可能会转换 Ordering[Int] o2Int (不能),或 Ordering[Int] o1到具有 def <(Ordered[Int]) 的东西方法,例如 Ordered[Ordered[Int]] .碰巧它必须停止搜索,因为它似乎可以无限期地循环。该规则在规范中给出,p。 107 到 109(2.9 版的规范)。但是,停止搜索的规则是悲观的,它可能会丢弃可能成功的搜索行,因此编译器认为它必须报告这一点。而实际上,这里的大部分时间,循环都被适本地丢弃了,并且不存在解决方案。这就是令人惊讶的错误消息的原因。我认为更简单的错误也应该报告,并且更加突出。

让我就隐式搜索中为什么可能存在循环给出一些有限的解释。可能有
implicit def f(implicit a: A): B

这意味着如果你有一个隐含的 A ,你有一个隐含的 B也。这样就可以在类型之间建立一个图表: A提供 B .比这更复杂,它实际上是一个超图: implcit def f(implicit a: A, implicit b: B): C : AB提供 C .

使用泛型,你有无限数量的类型和无限(超)图,通过子类型化变得更加复杂(如果你需要 A,任何 A 的子类型都可以。添加协方差隐含的子类型规则/逆变)

该图可能包含循环:得到一个 A ,你可以只提供一个 B ;获得 B ,你可以只提供一个 C ;获得 C ,您只需提供一个 A .如果您提供 A ,你会得到一个 A ,这是无用的,必须删除该搜索行。在这种情况下,这不是问题:这是一个实际循环,不存在通过丢弃可能的解决方案来绕过可能的解决方案的风险。

但它可能更复杂。由于图是无限的,搜索可能是无限的而不完全循环。如果你有
implicit def[A](x: X[X[A]]): X[A] 

那么如果你找 X[Int] , 你可以找 X[X[Int]]取而代之的是,然后,按照相同的规则,您查找 X[X[X[Int]]]等等。它并不完全循环,但编译器不会追踪这些行并将其称为发散。除了可能有一个隐含的 X[X[X...X[Int]]]]]在隐含范围内的某个地方,这将使它成功。这就是编译器报告放弃这条探索线的原因。

关于scala - "diverging implicit expansion"scalac 消息是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7950014/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com