Generics trait val成员与抽象类型的Scala比较

Generics trait val成员与抽象类型的Scala比较,generics,scala,Generics,Scala,我试图弄明白如何用抽象类型而不是类型参数来表达下面的代码 trait Key[T] extends Ordered[Key[T]] { val key:T } case class DoubleKey(key:Double) extends Key[Double] { def compare(that:Key[Double]):Int = this.key compare that.key } 我目前的版本如下: trait Key extends Ordered[Key] {

我试图弄明白如何用抽象类型而不是类型参数来表达下面的代码

trait Key[T] extends Ordered[Key[T]] {
  val key:T
}

case class DoubleKey(key:Double) extends Key[Double] {
  def compare(that:Key[Double]):Int = this.key compare that.key
}
我目前的版本如下:

trait Key extends Ordered[Key] {
  type K 
  val key:K
}

case class DoubleKey(val key:Double) extends Key {
  type K = Double
  def compare(that:Key):Int = this.key compare that.key.asInstanceOf[K]
}
但是我不喜欢显式转换为类型K:
that.key.asInstanceOf[K]
。是否有更好的/其他的方法来使用抽象类型实现对抽象成员的排序

我还尝试确保
的类型为:Key
Double

def compare(that:Key{type K=Double}):Int=this.Key比较that.Key


但这也失败了,因为编译器认为没有定义比较。此外,是否有一种解决方案,通过限制K(例如,
类型K我认为您至少需要一个类型参数来指示
DoubleKey
和说
StringKey
不可比较。编写
DoubleKey(1.0)

使用当前设计,您可能会遇到类强制转换异常:

case class StringKey(val key:String) extends Key {
  type K = String
  def compare(that:Key):Int = this.key compare that.key.asInstanceOf[K]
}

StringKey("b") < DoubleKey(1.0) // ClassCastException
case类StringKey(val-key:String)扩展键{
类型K=字符串
def compare(that:Key):Int=this.Key比较that.Key.asInstanceOf[K]
}
StringKey(“b”)
下面是一个定义,它将在编译时强制执行约束,并将compare的定义拉入基本成员:

abstract class Key[K <% Ordered[K]] extends Ordered[Key[K]] {
  val key:K
  def compare(that:Key[K]): Int = key compare that.key
}

case class DoubleKey(key:Double) extends Key[Double]
case class StringKey(key:String) extends Key[String]

StringKey("b") < DoubleKey(1.0) // won't compile

abstract class Key[K在允许密钥安全排序的同时,从Key中删除type参数的唯一方法是定义从Key类型到ordered Key类型的隐式转换。这也使得比较方法变得简单

trait Key { type K ; val key : K }

object Key {
  type PKey[KK] = Key { type K = KK }
  implicit def keyIsOrdered[K <% Ordered[K]](lhs : PKey[K]) = new Ordered[PKey[K]] {
    def compare(rhs : PKey[K]) = lhs.key compare rhs.key
  }
}

case class DoubleKey(val key : Double) extends Key { type K = Double }
case class StringKey(val key : String) extends Key { type K = String }
trait Key{type K;val Key:K}
对象键{
类型PKey[KK]=Key{type K=KK}
隐式def KEYSORDED[K双键(23)<双键(34)
res3:Boolean=true
scala>StringKey(“foo”)StringKey(“foo”)
我建议完全避免在此处进行排序,并提供隐式对象进位排序[DoubleKey]。这使事情变得更简单……感谢您的回答!它比“已接受”的更简洁。
scala> DoubleKey(23) < DoubleKey(34)
res3: Boolean = true

scala> StringKey("foo") < StringKey("bar")
res4: Boolean = false

scala> StringKey("foo") < DoubleKey(23)
<console>:14: error: could not find implicit value for parameter ord: scala.math.Ordering[ScalaObject]
       StringKey("foo") < DoubleKey(23)