Scala:A 扩展 Ordered[A]

Jxe*_*xek 3 sorting generics scala

我刚刚开始学习 Scala,为了练习,我决定创建一个 Pair[A, B] 类,该类在排序时首先按 As 排序,然后按 Bs 排序。我的第一次尝试是这样的:

case class Pair[A <: Ordered[A], B <: Ordered[B]](val left: A, val right: B) extends Ordered[Pair[A, B]]
{
  override def compare(that: Pair[A, B]) = {
      val leftCompare = this.left.compare(that.left)
      if (leftCompare == 0)
        this.right.compare(that.right)
      else
        leftCompare
    }
}

object Main extends App
{
  List(Pair(1, "a"), Pair(5, "b"), Pair(5, "a"), Pair(1, "b")).sorted
}
Run Code Online (Sandbox Code Playgroud)

这就是我想要的方式,真的。我想扩展 Ordered 并让它工作,所以我可以做像 List(whatever).sortWith(_ < _) 或 List(whatever).sorted 之类的事情,就像我在 Main 中写的那样。我收到以下错误:

pair.scala:14: error: inferred type arguments [Int,String] do not conform to method apply's type parameter bounds [A <: Ordered[A],B <: Ordered[B]]
  List(Pair(1, "a"), Pair(5, "b"), Pair(5, "a"), Pair(1, "b")).sorted
Run Code Online (Sandbox Code Playgroud)

这对于列表中的每一对:

pair.scala:14: error: type mismatch;
 found   : Int(1)
 required: A
  List(Pair(1, "a"), Pair(5, "b"), Pair(5, "a"), Pair(1, "b")).sorted
Run Code Online (Sandbox Code Playgroud)

这也是,我不了解:

pair.scala:14: error: diverging implicit expansion for type scala.math.Ordering[Pair[_ >: A with A with A with A <: scala.math.Ordered[_ >: A with A with A with A <: scala.math.Ordered[_ >: A with A with A with A]], _ >: B with B with B with B <: scala.math.Ordered[_ >: B with B with B with B <: scala.math.Ordered[_ >: B with B with B with B]]]]
starting with method $conforms in object Predef
  List(Pair(1, "a"), Pair(5, "b"), Pair(5, "a"), Pair(1, "b")).sorted
Run Code Online (Sandbox Code Playgroud)

我设法让它排序,但只能通过编写知道它们正在排序的类型的排序函数,而不是仅仅知道它们正在排序可排序的类型。正如我所提到的,这就是这些“了解类型”的版本:

case class Pair[A, B](val left: A, val right: B)
{}

object Main extends App
{
  val pairs = Array(Pair(1, "a"), Pair(5, "b"), Pair(5, "a"), Pair(1, "b"))
  Sorting.quickSort(pairs)(Ordering[(Int, String)].on(x => (x.left, x.right)))
  println(pairs.toList)
}
Run Code Online (Sandbox Code Playgroud)

case class Pair[A, B](val left: A, val right: B)
{}

object Main extends App
{
  val intStringSort = (x: Pair[Int, String], y: Pair[Int, String]) => {
    val intCompare = x.left - y.left
    if (intCompare == 0)
      x.right.compare(y.right) < 0
    else
      intCompare < 0
  }
  println(List(Pair(1, "a"), Pair(5, "b"), Pair(5, "a"), Pair(1, "b")).sortWith(intStringSort))
}
Run Code Online (Sandbox Code Playgroud)

提前致谢。

use*_*379 5

使用<%代替<:

case class Pair[A <% Ordered[A], B <% Ordered[B]]
Run Code Online (Sandbox Code Playgroud)

因为既不是Int也不StringOrdered

更新:

但是存在从Intto RichIntwhich isOrdered[Int]和 from Stringto StringOpswhich is 的隐式转换Ordered[String]

<%意味着对象可以隐式转换为定义的类型。例如,A <% Ordered[A]对于Int装置有从一个隐式转换IntOrdered[Int]它是:

implicit def intWrapper(x: Int)         = new runtime.RichInt(x)
Run Code Online (Sandbox Code Playgroud)

scala.Predef该自动导入。RichIntOrdered[Int]。对 执行类似的步骤String