scala - 使用"sortBy"时混淆"发散隐式扩展"错误

Tom*_*ong 9 scala implicit scala-collections

我想知道为什么List(3,2,1).toIndexedSeq.sortBy(x=>x)不起作用:

scala> List(3,2,1).toIndexedSeq.sortBy(x=>x) // Wrong
<console>:8: error: missing parameter type
              List(3,2,1).toIndexedSeq.sortBy(x=>x)
                                              ^
<console>:8: error: diverging implicit expansion for type scala.math.Ordering[B]
starting with method Tuple9 in object Ordering
              List(3,2,1).toIndexedSeq.sortBy(x=>x)
                                             ^

scala> Vector(3,2,1).sortBy(x=>x) // OK
res: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)

scala> Vector(3,2,1).asInstanceOf[IndexedSeq[Int]].sortBy(x=>x) // OK
res: IndexedSeq[Int] = Vector(1, 2, 3)

scala> List(3,2,1).toIndexedSeq.sortBy((x:Int)=>x) // OK
res: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

Lui*_*hys 6

如果你看一下toIndexedSeqon 的类型签名,List你会看到它需要一个类型参数B,它可以是任何超类型A:

def toIndexedSeq [B >: A] : IndexedSeq[B] 
Run Code Online (Sandbox Code Playgroud)

如果省略那个类型参数,那么编译器基本上必须猜测你的意思,尽可能采用最具体的类型.你可能意味着List(3,2,1).toIndexedSeq[Any],当然不能排序,因为没有Ordering[Any].似乎编译器不会播放"猜测类型参数",直到检查整个表达式的正确输入(也许有人知道编译器内部的东西可以扩展这个).

为了使其工作,你可以a)自己提供所需的类型参数,即

List(3,2,1).toIndexedSeq[Int].sortBy(x=>x)
Run Code Online (Sandbox Code Playgroud)

或者b)将表达式分成两部分,以便在调用之前必须推断出类型参数sortBy:

val lst = List(3,2,1).toIndexedSeq; lst.sortBy(x=>x)
Run Code Online (Sandbox Code Playgroud)

编辑:

这可能是因为sortBy需要Function1争论.签名sortBy

def sortBy [B] (f: (A) => B)(implicit ord: Ordering[B]): IndexedSeq[A] 
Run Code Online (Sandbox Code Playgroud)

sorted(你应该使用它!)工作正常List(3,2,1).toIndexedSeq.sorted

def sorted [B >: A] (implicit ord: Ordering[B]): IndexedSeq[A] 
Run Code Online (Sandbox Code Playgroud)

我不确定为什么Function1会导致这个问题而且我要睡觉所以不能再考虑它...