如何将 Int 转换为有序 (Scala)
Posted
技术标签:
【中文标题】如何将 Int 转换为有序 (Scala)【英文标题】:How to convert an Int into Ordered (Scala) 【发布时间】:2021-10-20 09:15:06 【问题描述】:我在 Scala 中声明了一个 Value 类:
sealed abstract class Value extends Expression with Ordered[Value]
type T <: Ordered[T]
def value: T
override def compare(that: Value): Int = ...
类型约束T <: ordered>compare方法委托给value: T
。
然后是一个具体的 IntValue 为:
case class IntValue(value: Int) extends Value
type T = Int
// ...
但是,当我尝试编译此代码时,我得到以下信息:''
... incompatible type in overriding
[error] type T <: Ordered[IntValue.this.T] (defined in class Value);
[error] found : Int
[error] required: <: Ordered[IntValue.this.T]
[error] (which expands to) <: Ordered[Int]
[error] type T = Int
我认为我应该在这里使用一些隐式转换,但我不清楚如何进行。
【问题讨论】:
您确定您的错误与您的代码的当前版本有关吗?在代码中你有Ordered
。在错误中你有Ordering
。
谢谢,@DmytroMitin,你是对的。我修复了错误消息。
@LuisMiguelMejíaSuárez 结果发现元问题是将compare
从T
委托给Value
:)
【参考方案1】:
错误是关于覆盖中的不兼容类型,而不是关于隐式。
您应该删除上限type T <: Ordered[T]
。
Int
不扩展 Ordered
。
尝试类型参数而不是类型成员
sealed abstract class Value[T] extends /*Expression with*/ Ordered[Value[T]]
def value: T
override def compare(that: Value[T]): Int
case class IntValue(value: Int) extends Value[Int]
override def compare(that: Value[Int]): Int = value.compare(that.value)
与成员类型相似的代码
sealed abstract class Value extends /*Expression with*/ Ordered[Value type T = self.T] self =>
type T
def value: T
override def compare(that: Value type T = self.T): Int
case class IntValue(value: Int) extends Value
type T = Int
override def compare(that: Value type T = Int): Int = value.compare(that.value)
不可能因为Error: illegal cyclic reference
。
Scala: Abstract types vs generics
https://typelevel.org/blog/2015/07/13/type-members-parameters.html
https://www.youtube.com/watch?v=R8GksuRw3VI
https://tpolecat.github.io/2015/04/29/f-bounds.html
如果你想委托,那么你应该使用 type class Ordering
而不是 OOP trait Ordered
。 Int
没有扩展 Ordered
但有一个 Ordering
的实例用于 Int
sealed abstract class Value[T]
def value: T
case class IntValue(value: Int) extends Value[Int]
implicit def valueOrdering[T, A](implicit
ev: A <:< Value[T],
ordering: Ordering[T]
): Ordering[A] = ordering.on(_.value)
import Ordering.Implicits._
IntValue(1) < IntValue(2) // -1
或
import Ordered._
IntValue(1) < IntValue(2) // true
IntValue(1).compare(IntValue(2)) // -1
类型类的方法可以用于类型成员
sealed abstract class Value
type T
def value: T
case class IntValue(value: Int) extends Value
override type T = Int
implicit def valueOrdering[A <: Value](implicit
ordering: Ordering[A#T]
): Ordering[A] = ordering.on(_.value)
// implicit def valueOrdering[_T, A](implicit
// ev: A <:< Value type T = _T ,
// ordering: Ordering[_T]
// ): Ordering[A] = ordering.on(_.value)
【讨论】:
感谢您的澄清@DmytroMitin。类型约束 T <: ordered>compare方法委托给“字段”value: T
。
@RodrigoBonifacio 好吧,Int
不会扩展 Ordered
。如果你想委托,那么你应该使用类型类 Ordering
而不是 OOP 特征 Ordered
。 Int
没有扩展 Ordered
,但有一个 Ordering
实例用于 Int
。
谢谢,@DmytroMitin!它就像一个魅力。
@RodrigoBonifacio 顺便说一下,类型类的方法可以用于类型成员。再看一次更新。以上是关于如何将 Int 转换为有序 (Scala)的主要内容,如果未能解决你的问题,请参考以下文章
如何在 scala 中将 RDD[(int, string)] 转换为 Dataframe