2014-12-20 6 views
5

Was ist los mit diesem einfachen Scala-Code?Eine Liste von Tupeln mit Scala falten

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 anderen funktionalen Sprachen (zB F #) Dies funktioniert:

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

Antwort

12

Die fold Verfahren einen assoziativen Betreiber übernehmen und in der Theorie können (zB bei der Parallelität verwendet wird) in beliebigen durchgeführt werden Auftrag. Die Signatur macht somit deutlich, dass der Akkumulationstyp ein Supertyp des Elements Sammlung sein muss:

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

Die abgeleitete Supertyp (String, Int) und Int ist Any.

Dies ist alles in der API documentation beschrieben.


Was Sie wollen, ist ein foldLeft oder foldRight die von der Art diese Einschränkung nicht haben:

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

Deshalb:

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

oder

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