scala-令人困惑的“发散的隐式展开";使用"sortBy"时出现错误 [英] scala - Confusing "diverging implicit expansion" error when using "sortBy"

查看:208
本文介绍了scala-令人困惑的“发散的隐式展开";使用"sortBy"时出现错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道为什么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)
 

解决方案

如果在List上查看toIndexedSeq的类型签名,您会看到它带有类型参数B,该参数可以是任何超类型的A:

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

如果省略该类型参数,则编译器实质上必须猜测您的意思,并尽可能采用最具体的类型.您可能本来是List(3,2,1).toIndexedSeq[Any]的意思,由于没有Ordering[Any],因此当然无法对其进行排序.似乎直到检查完整个表达式的正确键入后,编译器才扮演猜测类型参数"的角色(也许知道编译器内部知识的人可以对此进行扩展).

要使其正常工作,您可以a)自己提供所需的类型参数,即

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

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

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

可能是因为sortBy接受了Function1参数. sortBy的签名是

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

sorted(您应该改用它!)在List(3,2,1).toIndexedSeq.sorted

下可以正常工作

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

我不确定为什么Function1会导致此问题,并且我要上床睡觉,所以无法进一步考虑...

I wonder why List(3,2,1).toIndexedSeq.sortBy(x=>x) doesn't work:

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:

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]. 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 i.e.

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:

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

Edit:

It's probably because sortBy takes a Function1 argument. The signature of sortBy is

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

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...

这篇关于scala-令人困惑的“发散的隐式展开";使用"sortBy"时出现错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆