scala 未为订单定义隐式排序

erhoui1w  于 2023-04-21  发布在  Scala
关注(0)|答案(1)|浏览(98)

我想定义一个集合类,并要求其元素为Ordered
考虑下面的代码:

class MyCollection[K: Ordered[K]] {
  def func(seq: Seq[K]): Unit = {
    seq.sorted
  }
}

编译器将报告错误No implicit Ordering defined for ord: Ordering[K]
我做错了什么吗?假设我们已经有了约束K: Ordered[K]

vhmi4jdf

vhmi4jdf1#

您应该用途:

class MyCollection[K <: Ordered[K]] {
  def func(seq: Seq[K]): Unit =
    seq.sorted
}
class MyCollection[K](implicit ev: K <:< Ordered[K]) {
  def func(seq: Seq[K]): Unit =
    seq.sorted
}
class MyCollection[K](implicit ev: K => Ordered[K]) {
  def func(seq: Seq[K]): Unit =
    seq.sorted
}

(from从强到弱的假设)

class MyCollection[K: Ordering] {
  def func(seq: Seq[K]): Unit =
    seq.sorted
}

现在定义了OrderedOrdering,使得约束K => Ordered[K]K: Ordering实际上是等价的。实际上,Ordering.ordered在一个方向上将一个变换为另一个,Ordered.orderingToOrdered在另一个方向上变换

def test[K](implicit ev: K => Ordered[K]) =
  implicitly[Ordering[K]] // compiles

def test[K: Ordering] =
  implicitly[K => Ordered[K]] // compiles

上下文绑定MyCollection[K: Ordering]MyCollection[K](implicit ev: Ordering[K])的语法糖。这就是为什么[K: Ordered[K]]因为类型不匹配而根本无法编译。
Ordering是一个type class,但Ordered不是。Ordered是一个普通的OOP trait(你是在OOP风格中扩展它,而不是在FP风格中定义它的隐式示例)。这就是为什么虽然[K: Ordered]编译,但它在语义上是不正确的(隐式不会被发现)。
Ordering and Ordered and comparing Options
Scala Ordering, Ordered, and View Bound
Get Ordering from Ordered in Scala

相关问题