2016-01-07 3 views
1

Для педагогических целей я внедрил перечисление, используя объекты перечисления и случая. Мне нравится версия Enumeration, хотя она не может предупреждать о недостающих случаях в инструкции соответствия.Перечисления, порядок и импликации объектов объекта

Я попытался написать эквивалент с использованием объектов case, но обнаружил, что, хотя он компилируется, он не запускается. В частности, он, кажется, входит в бесконечный цикл во время выполнения (однако я не смог подтвердить это в отладчике). Вот код, который я пытаюсь запустить:

sealed abstract class Suit extends Ordered[Suit] { 
    val name: String 
    val priority: Int 
    override def toString = name 
    def compare(that: Suit) = priority-that.priority 
} 
case object Spades extends Suit { val name = "Spades"; val priority = 0 } 
case object Hearts extends Suit { val name = "Hearts"; val priority = 1 } 
case object Diamonds extends Suit { val name = "Diamonds"; val priority = 2 } 
case object Clubs extends Suit { val name = "Clubs"; val priority = 3 } 

object Suit { 
    implicit def ordering[A <: Suit]: Ordering[A] = Suit.ordering 
    def suits = List(Clubs,Spades).sorted 
} 

Если я ввожу этот код в РЕПЛ (через режим вставки), или если я скомпилировать его в Eclipse, все кажется хорошо. Но если я попытаюсь проверить метод костюмов объекта Suit, запуск просто зависает, и я должен его закончить.

Я пробовал большинство, если не все предложения, которые я нашел здесь, в StackOverflow относительно implicits (например, не определяя класс Suit для расширения Ordered [Suit] и вместо этого задавая заказ непосредственно для этого класса. собрали однако.

Рабочие предложения высоко ценится.

ответ

2
object Suit { 
    implicit def ordering[A <: Suit]: Ordering[A] = Suit.ordering 
} 

это бесконечный цикл, ordering себя вызовы. Я думаю, что вы хотите Ordering[Suit], это не имеет смысла в этом случае обратиться за упорядочение подтипа A от Suit (это будет один отдельный случайный объект).

Существует уже неявное упорядочение для типов, которые простираются Ordered, так что вам не нужно даже построить один:

implicitly[Ordering[Suit]] // aka Ordering.ordered[Suit] 

Так следующее просто работает:

object Suit { 
    def suits = List[Suit](Clubs, Spades).sorted 
} 

Обратите внимание, что List(Clubs, Spades).sorted не будет работать,, потому что тип выбранного типа списка - Suit with Product и как-то это создает неспособность найти однозначный порядок.

+0

Упс! Ты прав. Я этого не заметил. Я попробую ваше предложение. – Phasmid

+0

Увидели свое редактирование сейчас. Благодарю. Как вы говорите, он работает только после того, как тип списка явно указан как Костюм. Это кажется странным, но это приемлемо. – Phasmid

0

Часть проблемы, с которой я столкнулся раньше, заключалась в том, что Suit фактически расширяет черту под названием Concept, которую я здесь не показывал (в попытке упростить вещи).

Однако это фактически позволяет немного улучшить ответ на 0 __, потому что мне больше не нужно явно указывать тип моего списка. Вот код, по крайней мере, соответствующие детали:

trait Concept extends Ordered[Concept]{ 
    val name: String 
    val priority: Int 
    override def toString = name 
    def compare(that: Concept) = priority-that.priority 
} 
sealed trait Suit extends Concept { 
} 
object Concept { 
    implicit def ordering[A <: Concept]: Ordering[A] = Ordering.by(_.priority) 
} 
case object Spades extends Suit { val name = "Spades"; val priority = 0 } 
case object Hearts extends Suit { val name = "Hearts"; val priority = 1 } 
case object Diamonds extends Suit { val name = "Diamonds"; val priority = 2 } 
case object Clubs extends Suit { val name = "Clubs"; val priority = 3 } 
object Suit { 
    import scala.math.Ordered.orderingToOrdered 
    def suits = List(Clubs,Spades).sorted 
}