简体   繁体   English

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

[英]scala - Confusing “diverging implicit expansion” error when using “sortBy”

I wonder why List(3,2,1).toIndexedSeq.sortBy(x=>x) doesn't work: 我想知道为什么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)

If you look at the type signature of toIndexedSeq on List you'll see it takes a type parameter B , which can be any supertype of A : 如果你看一下ListtoIndexedSeq的类型签名,你会看到它需要一个类型参数B ,它可以是A任何超类型:

def toIndexedSeq [B >: A] : IndexedSeq[B] 

If you leave out that type parameter then the compiler essentially has to guess what you meant, taking the most specific type possible. 如果省略那个类型参数,那么编译器基本上必须猜测你的意思,尽可能采用最具体的类型。 You could have meant List(3,2,1).toIndexedSeq[Any] , which of course can't be sorted since there's no Ordering[Any] . 你可能意味着List(3,2,1).toIndexedSeq[Any] ,当然因为没有Ordering[Any]无法Ordering[Any] It seems the compiler doesn't play "guess the type parameter" until the whole expression has been checked for correct typing (maybe someone who knows something about compiler internals can expand on this). 似乎编译器不会播放“猜测类型参数”,直到检查整个表达式的正确输入(也许有人知道编译器内部的东西可以扩展这个)。

To make it work you can either a) provide the required type parameter yourself ie 为了使其工作,你可以a)自己提供所需的类型参数,即

List(3,2,1).toIndexedSeq[Int].sortBy(x=>x)

or b) separate the expression into two so that the type parameter has to be inferred before calling sortBy : 或者b)将表达式分成两部分,以便在调用sortBy之前必须推断出type参数:

val lst = List(3,2,1).toIndexedSeq; lst.sortBy(x=>x)

Edit: 编辑:

It's probably because sortBy takes a Function1 argument. 这可能是因为sortBy采用了Function1参数。 The signature of sortBy is sortBy的签名是

def sortBy [B] (f: (A) => B)(implicit ord: Ordering[B]): IndexedSeq[A] 

whereas sorted (which you should use instead!) works fine with List(3,2,1).toIndexedSeq.sorted sorted (你应该使用它!)适用于List(3,2,1).toIndexedSeq.sorted

def sorted [B >: A] (implicit ord: Ordering[B]): IndexedSeq[A] 

I'm not sure exactly why Function1 causes this problem and I'm going to bed so can't think about it further... 我不确定为什么Function1会导致这个问题而且我要睡觉所以不能再考虑它...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM