2012-02-29 9 views
9

Mi chiedo perché List(3,2,1).toIndexedSeq.sortBy(x=>x) non funziona:scala - Confondere "divergente implicita espansione" l'errore quando si utilizza "sortby"

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) 
+2

Inoltre, 'Elenco (3,2,1) .toIndexedSeq.sortBy (identità)' dà un errore più utile e 'Elenco (3,2,1). toIndexedSeq [Int] .sortBy (x => x) 'funziona bene. – dhg

+0

Nota che puoi cambiare sortBy e toIndexedSeq: 'List (3, 2, 1) .sortBy (x => x). toIndexedSeq' –

risposta

6

Se si guarda alla firma tipo di toIndexedSeq su List vedrete che ci vuole un parametro di tipo B, che può essere qualsiasi supertipo di A:

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

Se si lascia che tipo di parametro il compilatore ha essenzialmente di indovinare che cosa volevi dire, prendendo il tipo più specifico possibile . Avresti potuto significare List(3,2,1).toIndexedSeq[Any], che ovviamente non può essere ordinato poiché non c'è lo Ordering[Any]. Sembra che il compilatore non giochi "indovina il parametro tipo" fino a quando l'intera espressione è stata controllata per la digitazione corretta (forse qualcuno che sa qualcosa sui componenti interni del compilatore può espandersi su questo).

Per farlo funzionare è possibile a) fornire il parametro di tipo richiesto da soli vale a dire

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

oppure b) separare l'espressione in due in modo che il parametro di tipo deve essere dedotto prima di chiamare sortBy:

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

Edit:

è probabilmente perché sortBy prende un argomento Function1. La firma di sortBy è

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

mentre sorted (che si dovrebbe usare invece!) Funziona bene con List(3,2,1).toIndexedSeq.sorted

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

io non so esattamente il motivo per cui Function1 cause di questo problema e ho intenzione di il letto quindi non può pensarci ulteriormente ...

+0

funziona dal 2,10. –

Problemi correlati