如何将 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 结果发现元问题是将compareT 委托给Value :) 【参考方案1】:

错误是关于覆盖中的不兼容类型,而不是关于隐式。

您应该删除上限type T &lt;: 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 OrderedInt 没有扩展 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 特征 OrderedInt 没有扩展 Ordered,但有一个 Ordering 实例用于 Int 谢谢,@DmytroMitin!它就像一个魅力。 @RodrigoBonifacio 顺便说一下,类型类的方法可以用于类型成员。再看一次更新。

以上是关于如何将 Int 转换为有序 (Scala)的主要内容,如果未能解决你的问题,请参考以下文章

如何在 scala 中将 RDD[(int, string)] 转换为 Dataframe

如何将折叠左侧运算符“:/”转换为scala中的foldLeft函数?

如何将数据框列传递给scala函数

将 Scala 列表转换为元组?

在Scala中将字符串转换为运算符

如何将任何数字转换为长数