Quando costruisco una lista utilizzando foldLeft
Ho spesso infastidito dover digitare in modo esplicito il parametro iniettato e avrei voluto semplicemente usare `Nil' invece - Ecco un esempio artificioso:Perché non passa Nil a piegarsi?
scala> List(1,2,3).foldLeft(List[Int]())((x,y) => y :: x)
res17: List[Int] = List(3, 2, 1)
scala> List(1,2,3).foldLeft(Nil)((x, y) => y :: x)
<console>:10: error: type mismatch;
found : List[Int]
required: scala.collection.immutable.Nil.type
List(1,2,3).foldLeft(Nil)((x,y) => y :: x)
Questo non è poi così male con un List[Int]
ma non appena inizi a utilizzare elenchi delle tue classi, che quasi sicuramente avranno nomi più lunghi, o persino elenchi di tuple o altri contenitori, quindi ci sono più nomi di classe che devi specificare, diventa orrendo:
list.foldLeft(List.empty[(SomethingClass, SomethingElseClass)]) { (x,y) => y :: x }
Sto supponendo che il re ma non funziona, mentre con qualcosa come 5 :: Nil
il compilatore può dedurre il tipo della lista vuota per essere List[Int]
, ma quando Nil
viene passato come parametro a foldLeft
non ha abbastanza informazioni per farlo, e da il tempo in cui arriva a essere usato il suo tipo è impostato. Ma - è proprio vero che non poteva? Non potrebbe inferire il tipo dal tipo restituito della funzione passata come secondo argomento?
E se no, c'è qualche idioma più ordinario di cui non so nulla?
È deplorevole che Scala non possa inferire il tipo per questo tipo di situazioni. Speriamo che questo sia modificato in futuro. –
Non dovrebbe essere troppo un problema nella pratica. Se hai a che fare con alcune classi specifiche, fai un alias di tipo in alto 'type S = (SomethingClass, SomethingElseClass)' o 'val nil = List.empty [(SomethingClass, SomethingElseClass)]'. Se stai scrivendo un metodo generico, i tuoi tipi avranno già alias brevi come 'T' e' U'. –