Начинающий: как мне сказать "любой суперкласс универсального A" - PullRequest
5 голосов
/ 20 января 2012

Я играю с примером быстрой сортировки в начале Scala By Example и пытаюсь адаптировать его для универсального типа A, а не просто Int s.

То, что я до сих пор работаю, это

def sort[A <: Ordered[A]](xs: Array[A]) 

Что позволяет sort работать на всех типах, которые рефлексивно упорядочены, подобно RichBoolean.

Но я также хотел бы разрешить типам A, где они расширяются, Ordered[B], где B - суперкласс A (например, все, что расширяется Ordered[Any]).

Как я могу это сказать?


То, что я действительно получил на работу, благодаря ответу Agilesteel :

case class X( i : Int ) extends Ordered[X] {
  def compare( x : X ) = x.i - i
}

class Y( i : Int, j : Int ) extends X(i)

case class Z( i : Int ) extends Ordered[Any] {
  def compare( a : Any ) : Int = {
    if (! a.isInstanceOf[Z] ) 
      sys.error("whoops") 

    val z = a.asInstanceOf[Z]
    z.i - i
  }
}

object QuickSort {
  def main( args : Array[String] ) {
    val xs = Array( 3, 1, 2, 4 ) map X
    sort( xs );
    val ys = Array( 3, 1, 2, 4 ) map { i => new Y(i, -i) }
    sort[X,Y]( ys );
    val zs = Array( 3, 1, 2, 4 ) map Z
    sort[Any,Z]( zs );
  }
  def sort[B >: A, A <: Ordered[B]](xs: Array[A]) {
    def swap(i: Int, j: Int) {
      val t = xs(i); xs(i) = xs(j); xs(j) = t;
    }
    def sort1(l: Int, r: Int) {
      val pivot = xs((l + r) / 2)
        var i = 1; var j = r
      while (i <= j) {
        while (xs(i) < pivot) i += 1
        while (xs(j) > pivot) j -= 1
        if (i <= j) {
          swap(i, j)
          i += 1
          j += 1
        }
      }
      if (l < j) sort1(l, j)
      if (j < r) sort1(i, r)
    }
    sort1(0, xs.length - 1)
  }
}

Я был введен в заблуждение, пытаясь использовать RichLong и RichBoolean в качестве типов тестов, поскольку они не являются на самом деле рефлексивными Ordered (они расширяют Ordered[Long] и Ordered[Boolean] вместо этого).

Ответы [ 2 ]

7 голосов
/ 20 января 2012

Как то так?

def sort[B >: A, A <: Ordered[B]](xs: Array[B]) 
1 голос
/ 20 января 2012

То, что вы ищете - это то, что происходит от черты Ordered или может рассматриваться как таковое. Существует множество неявных преобразований (называемых представлениями) из многих классов в Ordered, и вы также можете иметь свои собственные. Тем не менее, вы в конечном итоге:

def sort[A <% Ordered[A]](xs: Array[A]) = ...

<% - это всего лишь синтаксический сахар для def sort(xs: Array[A])(implicit cv: A => Ordered[A]) = .... Возможно, вы захотите взглянуть на этот замечательный сборник вопросов и ответов, если вам интересно, что происходит за кулисами последствий.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...