Sco*_*son 6 scala sortedmap scala-2.8 scala-collections
(我正在使用Scala nightlies,并在2.8.0b1 RC4中看到相同的行为.我是Scala的新手.)
我有两个SortedMap我想组成的联盟.这是我想要使用的代码:
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 }
}
Run Code Online (Sandbox Code Playgroud)
这里的想法是'隐含'语句意味着Xs可以转换为Ordered[X]s,然后将SortedMaps 组合成另一个SortedMap,而不仅仅是一个映射.
当我编译时,我得到了
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
Run Code Online (Sandbox Code Playgroud)
如果类型参数绑定是[A <% scala.math.Ordered[A]],而不是,我的问题似乎会消失[A <: scala.math.Ordered[A]].不幸的是,我甚至无法找出"命令"生活的方法!任何人都可以帮我追踪它吗?
如果做不到这一点,我打算做两个联盟的意图是什么SortedMap?如果我删除了返回类型的联合收割机(或将其更改为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)
Run Code Online (Sandbox Code Playgroud)
该类型的返回结果的++是Map[Int, Int],因为这将是很有道理的唯一类型的++一个方法MapLike对象返回.似乎++保留了sort的属性SortedMap,我想这是因为++使用抽象方法来进行连接,并且这些抽象方法被定义为保持映射的顺序.
为了拥有两个有序地图的联合,我建议你使用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)
Run Code Online (Sandbox Code Playgroud)
SortedMaptrait的这个实现声明了一个++返回a 的方法SortedMap.
现在,您对类型边界的问题有几个答案:
Ordered[T]是如果混在一类它指定该类别可以使用比较的性状<,>,=,>=,<=.您只需要定义compare(that: T)返回-1for this < that,1for this > that和0for 的抽象方法this == that.然后基于结果在特征中实现所有其他方法compare.
T <% U表示Scala中绑定的视图.这意味着类型T是子类型,U或者可以U通过范围中的隐式转换隐式转换为类型.代码工作,如果你把<%而与<:作为X不是一个亚型Ordered[X],但可以隐式转换为Ordered[X]使用OrderedX隐式转换.
编辑:关于你的评论.如果您正在使用scala.collection.immutable.SortedMap,那么您仍在编程接口而不是实现,因为不可变SortedMap定义为a trait.您可以将其视为更专业的特征scala.collection.SortedMap,它提供额外的操作(如++返回a SortedMap)和不可变的属性.这符合Scala哲学 - 更喜欢不变性 - 因此我没有看到使用不可变的任何问题SortedMap.在这种情况下,您可以保证结果肯定会被排序,并且由于集合是不可变的,因此无法更改.
虽然,我仍然觉得很奇怪,因为scala.collection.SortedMap它没有提供一个++返回SortedMap结果的方法.我所做的所有有限测试似乎都表明,两个连接的结果scala.collection.SortedMap确实产生了一个保存已排序属性的映射.