2009-04-25 4 views
5

У меня есть класс, который я хотел бы использовать в scala.collection.mutable.PriorityQueue, но я не хочу, чтобы он был упорядочен [A] только для этой цели. Я не рассматриваю порядок, который я хочу использовать в отношении PriorityQueue, как естественный порядок класса.Scala: Есть ли способ использовать PriorityQueue, как в Java?

class MyObject (sequence: Int, values: List[String]) ... 

Итак, в моем PriorityQueue я хотел бы, чтобы значения упорядочивались по 'sequence'. Однако только потому, что два объекта имеют одну и ту же последовательность, они не делают их естественными, так как содержание их «значений» может быть различным.

Здесь, на Java, приятно иметь альтернативный объект Comparator для PriorityQueue. Мой компаратор просто заказывал объекты в отношении их «последовательности» и игнорировал их «значения».

PriorityQueue класс должен быть параметризованы с «A <% упорядоченном [A]»

class PriorityQueue[A <% Ordered[A]] extends ... 

Из того, что я читал, это означает, что мой класс должен расширять Заказанный [A] или я должен предоставить «implicit def» type to Ordered [A], который, честно говоря, чувствует себя неэлегантным.

Решение Java кажется более «функциональным», что позволяет мне передавать объект-объект Comparator вместо того, чтобы вставлять меня в иерархию классов или monkeypatching моего класса.

Я понимаю, что есть альтернативы использованию PrioirityQueue, но я чувствую, что я могу столкнуться с кривой обучения Scala здесь и не хочу сдаваться без полного изучения этого дизайнерского решения.

Это просто неудачное решение в библиотеке Scala, или я не понимаю какое-то соглашение о вызове, которое делает PriorityQueue более полезным и «функциональным»?

Благодаря

ответ

9

Синтаксис

class PriorityQueue[A <% Ordered[A]] ... 

действительно просто свет обсахаривания на вершине

class PriorityQueue[A]()(implicit convert: A => Ordered[A]) ... 

Это означает, что вы можете написать свой собственный метод A => упорядоченную [A]

case class Foo(n: Int) 
def orderedFoo(f: Foo): Ordered[Foo] = new Ordered[Foo] { 
    def compare(other: Foo) = f.n.compare(other.n) 
} 

И вручную передайте его в свой конструктор PriorityQueue

new PriorityQueue[Foo]()(orderedFoo) 
3

Функция преобразования А на Заказанный [A] может играть роль Java компаратора. Функция должна быть видна только в области, где вы создаете PriorityQueue, поэтому она не станет «естественным порядком» для вашего объекта.

2

Объединяя оба (правильные) ответы перед этим в компилируемый код:

object o { 
    case class Foo(n: Int) 
    implicit def orderedFoo(f: Foo): Ordered[Foo] = new Ordered[Foo] { 
    def compare(other: Foo) = f.n.compare(other.n) 
    } 

    val x = new scala.collection.mutable.PriorityQueue[Foo]() 
} 

Его пример не будет составлять для вас только потому, что (я предположив) вы бросили его в компиляторе как есть. Вы не можете скомпилировать методы верхнего уровня в scala, все должно быть в объекте.

2

В scala 2.8.0, то PriorityQueue изменения в

class PriorityQueue[A](implicit ord : Ordering[A]) 

И Упорядочение [A] в Scala похож на компаратор в Java

Смежные вопросы