scala - 如何形成 scala SortedMaps 的联合?

标签 scala scala-2.8 scala-collections sortedmap

(我正在使用 Scala nightlies,并在 2.8.0b1 RC4 中看到相同的行为。我是 Scala 新手。)

我有两个 SortedMap s,我想组建工会。这是我想使用的代码:

import scala.collection._

object ViewBoundExample {
    class X
    def combine[Y](a: SortedMap[X, Y], b: SortedMap[X, Y]): SortedMap[X, Y] = {
        a ++ b
    }
    implicit def orderedX(x: X): Ordered[X] = new Ordered[X] { def compare(that: X) = 0 }
}

这里的想法是“隐式”声明意味着X s 可以转换为 Ordered[X] s,然后组合 SortedMap 是有意义的换成另一个 SortedMap ,而不仅仅是一张 map 。

当我编译时,我得到
sieversii:scala-2.8.0.Beta1-RC4 scott$ bin/scalac -versionScala compiler version
2.8.0.Beta1-RC4 -- Copyright 2002-2010, LAMP/EPFL

sieversii:scala-2.8.0.Beta1-RC4 scott$ bin/scalac ViewBoundExample.scala
ViewBoundExample.scala:8: error: type arguments [ViewBoundExample.X] do not
    conform to method ordered's type parameter bounds [A <: scala.math.Ordered[A]]
        a ++ b
          ^
one error found

如果该类型参数绑定(bind)是 [A <% scala.math.Ordered[A]],我的问题似乎会消失。 ,而不是 [A <: scala.math.Ordered[A]] .不幸的是,我什至无法弄清楚“有序”方法的位置!任何人都可以帮我追踪它吗?

如果做不到这一点,我该怎么做才能产生两个 SortedMap 的联合?年代?如果我删除 combine 的返回类型(或将其更改为 Map )一切正常 --- 但是我不能依赖返回被排序!

最佳答案

目前,您使用的是 scala.collection.SortedMap 特征,其 ++ 方法继承自 MapLike 特征。因此,您会看到以下行为:

scala> import scala.collection.SortedMap
import scala.collection.SortedMap

scala> val a = SortedMap(1->2, 3->4)
a: scala.collection.SortedMap[Int,Int] = Map(1 -> 2, 3 -> 4)

scala> val b = SortedMap(2->3, 4->5)
b: scala.collection.SortedMap[Int,Int] = Map(2 -> 3, 4 -> 5)

scala> a ++ b
res0: scala.collection.Map[Int,Int] = Map(1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5)

scala> b ++ a
res1: scala.collection.Map[Int,Int] = Map(1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5)
++ 的返回结果的类型是 Map[Int, Int] ,因为这将是 ++ 对象的 MapLike 方法返回的唯一类型。似乎 ++ 保留了 SortedMap 的 sorted 属性,我猜这是因为 ++ 使用抽象方法进行连接,并且这些抽象方法被定义为保持映射的顺序。

要合并两个已排序的 map ,我建议您使用 scala.collection.immutable.SortedMap
scala> import scala.collection.immutable.SortedMap
import scala.collection.immutable.SortedMap

scala> val a = SortedMap(1->2, 3->4)
a: scala.collection.immutable.SortedMap[Int,Int] = Map(1 -> 2, 3 -> 4)

scala> val b = SortedMap(2->3, 4->5)
b: scala.collection.immutable.SortedMap[Int,Int] = Map(2 -> 3, 4 -> 5)

scala> a ++ b
res2: scala.collection.immutable.SortedMap[Int,Int] = Map(1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5)

scala> b ++ a
res3: scala.collection.immutable.SortedMap[Int,Int] = Map(1 -> 2, 2 -> 3, 3 -> 4, 4 -> 5)

这个 SortedMap 特征的实现声明了一个 ++ 方法,该方法返回一个 SortedMap

现在有几个关于类型界限的问题的答案:
  • Ordered[T] 是一个特征,如果混合在一个类中,它指定可以使用 <>=>=<= 比较该类。你只需要定义抽象方法 compare(that: T) ,它返回 -1this < that1this > that0this == that 。然后根据 compare 的结果在 trait 中实现所有其他方法。
  • T <% U 表示在 Scala 中绑定(bind)的 View 。这意味着 T 类型要么是 U 的子类型,要么可以通过范围内的隐式转换隐式转换为 U。如果您放置 <% 但不使用 <:,则代码​​有效,因为 X 不是 Ordered[X] 的子类型,但可以使用 Ordered[X] 隐式转换隐式转换为 OrderedX

  • 编辑: 关于您的评论。如果您使用的是 scala.collection.immutable.SortedMap ,那么您仍在对接口(interface)而不是实现进行编程,因为不可变的 SortedMap 被定义为 trait 。您可以将其视为 scala.collection.SortedMap 的更特殊的特征,它提供额外的操作(如 ++ 返回 SortedMap )和不可变的属性。这符合 Scala 哲学——更喜欢不变性——因此我认为使用不可变 SortedMap 没有任何问题。在这种情况下,您可以保证结果肯定会排序,并且由于集合是不可变的,因此无法更改。

    尽管如此,我仍然觉得奇怪的是 scala.collection.SortedMap 不提供 ++ 方法,结果女巫返回 SortedMap 。我所做的所有有限测试似乎表明,两个 scala.collection.SortedMap 的串联结果确实产生了一个保留排序属性的映射。

    关于scala - 如何形成 scala SortedMaps 的联合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1938038/

    相关文章:

    scala - @karate如何将参数传递给 Gatling 模拟类中的特征文件?

    generics - 我无法正确获得此 Scala 通用声明

    scala - 为什么 Scala Option.tapEach 返回 Iterable,而不是 Option?

    scala - 如何用尾部映射列表项[Scala]

    scala - 我什么时候应该在scala中使用 "new"?

    scala - sbt项目的Jenkins静态代码分析

    java - 对象工具不是包 scala 的成员

    scala - Scala 2.8 中的 classOf[] 与 2.7 不同吗?

    Scala 2.8 Actor

    scala - 不理解 Scala 分隔延续的类型 (A @cpsParam[B,C])