2014-12-20 22 views
5

Cosa c'è che non va con questo semplice scala codice?Piegare una lista di tuple usando Scala

val l = List(("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 5)) 
l.fold(0) {(acc: Int, tup: (String, Int)) => acc + tup._2} 

:9: error: type mismatch; found : (Int, (String, Int)) => Int required: (Any, Any) => Any l.fold(0) {(acc: Int, tup: (String, Int)) => acc + tup._2}

In altri linguaggi funzionali (ad esempio, f #) funziona:

let l = [("a", 1); ("b", 2); ("c", 3); ("d", 4)];; 
List.fold(fun accm tup -> accm + (snd tup)) 0 l;; 
val it : int = 10 

risposta

12

Procedimento fold assume un operatore associativo e può in teoria (ad esempio quando si utilizza il parallelismo) eseguita in arbitraria ordine. La firma rende quindi evidente che il tipo di accumulo deve essere un super-tipo di elemento della collezione:

def fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1 

la dedotto super-tipo di (String, Int) e Int è Any.

Questo è tutto descritto nello API documentation.


quello che vuoi è un foldLeft o foldRight che non hanno questa restrizione del tipo:

def foldLeft[B](z: B)(f: (B, A) ⇒ B): B 

Pertanto:

l.foldLeft(0) { (acc, tup) => 
    acc + tup._2 
} 

o

(0 /: l) { 
    case (acc, (_, n)) => acc + n 
} 
Problemi correlati