Case 对象枚举、顺序和隐式
Case object enumerations, order and implicits
出于教学目的,我使用枚举和案例对象实现了一个枚举。我对 Enumeration 版本很满意,尽管它不能在匹配语句中警告丢失的情况。
我曾尝试编写等效的使用案例对象,但我发现,虽然它可以编译,但它不会 运行。特别是,它似乎在 运行 时间进入无限循环(但是我无法在调试器中确认这一点)。这是我正在尝试的代码 运行:
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
}
如果我将这段代码输入到 REPL(通过粘贴模式)或者如果我在 Eclipse 中编译它,一切都很好。但是,如果我尝试测试 Suit 对象的 suits 方法,运行 就会挂起,我必须终止它。
我已经尝试了我在 Whosebug 上找到的关于隐式的大部分(如果不是全部的话)建议(例如,不定义 Suit class 来扩展 Ordered[Suit] 而是直接为class。None 其中已编译。
非常感谢工作建议。
object Suit {
implicit def ordering[A <: Suit]: Ordering[A] = Suit.ordering
}
那是一个死循环,ordering
调用自己。我想你想要一个 Ordering[Suit]
,在这种情况下要求订购 Suit
的 sub-type A
是没有意义的(那将是一个个案对象)。
扩展 Ordered
的类型已经存在隐式排序,因此您甚至不需要构造一个:
implicitly[Ordering[Suit]] // aka Ordering.ordered[Suit]
因此以下内容有效:
object Suit {
def suits = List[Suit](Clubs, Spades).sorted
}
请注意,List(Clubs, Spades).sorted
将不起作用, 因为推断的列表元素类型是 Suit with Product
并且以某种方式导致无法找到明确的排序.
我之前遇到的部分问题是 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
}
出于教学目的,我使用枚举和案例对象实现了一个枚举。我对 Enumeration 版本很满意,尽管它不能在匹配语句中警告丢失的情况。
我曾尝试编写等效的使用案例对象,但我发现,虽然它可以编译,但它不会 运行。特别是,它似乎在 运行 时间进入无限循环(但是我无法在调试器中确认这一点)。这是我正在尝试的代码 运行:
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
}
如果我将这段代码输入到 REPL(通过粘贴模式)或者如果我在 Eclipse 中编译它,一切都很好。但是,如果我尝试测试 Suit 对象的 suits 方法,运行 就会挂起,我必须终止它。
我已经尝试了我在 Whosebug 上找到的关于隐式的大部分(如果不是全部的话)建议(例如,不定义 Suit class 来扩展 Ordered[Suit] 而是直接为class。None 其中已编译。
非常感谢工作建议。
object Suit {
implicit def ordering[A <: Suit]: Ordering[A] = Suit.ordering
}
那是一个死循环,ordering
调用自己。我想你想要一个 Ordering[Suit]
,在这种情况下要求订购 Suit
的 sub-type A
是没有意义的(那将是一个个案对象)。
扩展 Ordered
的类型已经存在隐式排序,因此您甚至不需要构造一个:
implicitly[Ordering[Suit]] // aka Ordering.ordered[Suit]
因此以下内容有效:
object Suit {
def suits = List[Suit](Clubs, Spades).sorted
}
请注意,List(Clubs, Spades).sorted
将不起作用, 因为推断的列表元素类型是 Suit with Product
并且以某种方式导致无法找到明确的排序.
我之前遇到的部分问题是 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
}