gpt4 book ai didi

scala - "No implicit ordering defined for U"的错误,其中扩展了 Ordered 的特征

转载 作者:行者123 更新时间:2023-12-01 11:46:07 24 4
gpt4 key购买 nike

在创建名为 test.WsTemp 的 ScalaIDE Worksheet 之后,我编写了下面的代码,并且在特征 Enum 中的一行中收到三个错误:

  1. scala.math.Ordering[U] 类型的发散隐式扩展,从特征 LowPriorityOrderingImplicits 中排序的方法开始
  2. 没有为 U 定义隐式 Ordering
  3. 排序方法的参数不足:(implicit ord: scala.math.Ordering[U])List[U],未指定值参数 ord

为什么这不起作用,因为很明显 Val 扩展了 Ordered[Val]

object WsTemp {
trait Val extends Ordered[Val] {
val id: Int
val name: String
final def compare(that: Val) = this.id - that.id
override def toString: String = name
}

trait Enum[U <: Val] {
protected def init: Set[U]
val all = init
val allOrdered = all.toList.sorted // <-- Receiving error here
val byId = all.map(x => (x.id, x)).toMap
val byName = all.map(x => (x.name, x)).toMap

def apply(id: Int) = byId.get(id)
def apply(name: String) = byName.get(name)
}

sealed class Value(val id: Int, val name: String) extends Val
object Suit extends Enum[Value] {
override def init: Set[Value] = //Set()
Set(
new Value(0, "Spade")
, new Value(1, "Club")
, new Value(2, "Diamond")
, new Value(3, "Heart")
)
val Spade = Suit.byId(0)
val Club = Suit.byId(1)
val Diamond = Suit.byId(2)
val Heart = Suit.byId(3)
}

val all = Suit.all
val allOrdered = Suit.allOrdered
val byId = Suit.byId
val byName = Suit.byName
val spade = Suit.Spade
}

最佳答案

OrderingOrdered都是不变的,所以 U 的事实是 Val 的子类型(由关系 U <: Val 表示)并不意味着 Ordering[Val]可以用作 Ordering[U] .所以即使Val延伸Ordered[Val]意味着你隐含地得到一个 Ordering[Val] , 这对 Ordering[U] 没有任何意义.

因此编译器提示它找不到类型为 Ordering[U] 的隐式值是正确的(这是调用 sorted 所必需的)。

这个问题很容易用一个模仿 Ordered 的小代码片段来说明。和 Ordering :

object WsTemp {
trait MyOrdered[T]

trait MyOrdering[T]
object MyOrdering {
implicit def toOrdering[A <% MyOrdered[A]]: MyOrdering[A] = new MyOrdering[A]{}
}

trait Val extends MyOrdered[Val]

def test[T](implicit ord: MyOrdering[T]) {}

trait Enum[U <: Val] {
def callTest() { test[U] }
}
}

这会产生以下错误:

<console>:20: error: could not find implicit value for parameter ord: WsTemp.MyOrdering[U]
def callTest() { test[U] }

但是如果你做 MyOrderedMyOrdering协变,这编译得很好:

trait MyOrdered[+T]      
trait MyOrdering[+T]
...

显然,您无法更改 scala 的 Ordering也不Ordered使它们不变。


现在,解决问题的一种方法是安排代码,使 Val不扩展 Ordered[Val] ,而是扩展 Ordered[X]其中 X是您想要 Ordering 的实际类型对于(这里,X = U)。这可以通过F-bounded 多态性来实现:

trait Val[Self<:Val[Self]] extends Ordered[Self] {
//...
}

trait Enum[U <: Val[U]] {
//...
}

sealed class Value(val id: Int, val name: String) extends Val[Value]
//...

U现在是 Val[U] 的子类型,它是 Ordered[U] 的子类型(与以前的 Ordered[Val] 的子类型相反),因此您现在隐式获得 Ordering[U]。 ,它(隐含地)传递给 sorted .问题解决了。

关于scala - "No implicit ordering defined for U"的错误,其中扩展了 Ordered 的特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15057487/

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