定义具有抽象类型的特征的排序,该排序仅针对兼容类型进行编译?

发布于 2024-11-07 05:14:10 字数 131 浏览 0 评论 0原文

假设以下特征:

trait A {
  type B       
}

是否有任何方法可以使其成为有序类型,其中只有具有相同 B 的 A 可以进行比较,并且这是在编译时强制执行的?

Assume the following trait:

trait A {
  type B       
}

Is there any way of making this into an ordered type, where only A's with the same B's can be compared, and this is enforced in compile time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自由范儿 2024-11-14 05:14:10

是的,通过隐式(使用类型别名使事情变得更加干燥),

type AA[T] = A { type B = T }

implicit def aIsOrdered[T](a : AA[T]) = new Ordered[AA[T]] {
  def compare(that : AA[T]) = 0
}

示例 REPL 会话,

scala> val ai1 = new A { type B = Int }
ai1: java.lang.Object with A{type B = Int} = $anon$1@1ec264c

scala> val ai2 = new A { type B = Int }
ai2: java.lang.Object with A{type B = Int} = $anon$1@1a8fb1b

scala> val ad = new A { type B = Double }
ad: java.lang.Object with A{type B = Double} = $anon$1@891a0

scala> ai1 < ai2
res2: Boolean = false

scala> ai1 < ad
<console>:16: error: type mismatch;
 found   : ad.type (with underlying type java.lang.Object with A{type B = Double})
 required: AA[Int]
       ai1 < ad
             ^

编辑...

感谢 scala.math.LowPriorityOrderingImplicits 中的隐式定义,此定义足以为我们提供对应的Ordering类型的类实例。这允许我们将 A 与需要排序的类型一起使用,例如。 scala.collection.SortedSet,

scala> implicitly[Ordering[AA[Int]]]
res0: Ordering[AA[Int]] = scala.math.LowPriorityOrderingImplicits$anon$4@39cc63

scala> import scala.collection.SortedSet
import scala.collection.SortedSet

scala> val s = SortedSet(ai1, ai2)
s: scala.collection.SortedSet[java.lang.Object with A{type B = Int}] = TreeSet($anon$1@1a8fb1b)

Yes, via an implicit (with a type alias to make things a little more DRY),

type AA[T] = A { type B = T }

implicit def aIsOrdered[T](a : AA[T]) = new Ordered[AA[T]] {
  def compare(that : AA[T]) = 0
}

Sample REPL session,

scala> val ai1 = new A { type B = Int }
ai1: java.lang.Object with A{type B = Int} = $anon$1@1ec264c

scala> val ai2 = new A { type B = Int }
ai2: java.lang.Object with A{type B = Int} = $anon$1@1a8fb1b

scala> val ad = new A { type B = Double }
ad: java.lang.Object with A{type B = Double} = $anon$1@891a0

scala> ai1 < ai2
res2: Boolean = false

scala> ai1 < ad
<console>:16: error: type mismatch;
 found   : ad.type (with underlying type java.lang.Object with A{type B = Double})
 required: AA[Int]
       ai1 < ad
             ^

Edit ...

Thanks to the implicit definitions in scala.math.LowPriorityOrderingImplicits this defintion is sufficient to provide us with corresponding Ordering type class instances. This allows us to use A with types which require Orderings, eg. a scala.collection.SortedSet,

scala> implicitly[Ordering[AA[Int]]]
res0: Ordering[AA[Int]] = scala.math.LowPriorityOrderingImplicits$anon$4@39cc63

scala> import scala.collection.SortedSet
import scala.collection.SortedSet

scala> val s = SortedSet(ai1, ai2)
s: scala.collection.SortedSet[java.lang.Object with A{type B = Int}] = TreeSet($anon$1@1a8fb1b)
北方的韩爷 2024-11-14 05:14:10

B 作为 A 的参数怎么样?

trait A[B] {
    compare(x: A[B]): Int
}

How about making B a parameter of A?

trait A[B] {
    compare(x: A[B]): Int
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文