2014-12-20 3 views
5

Что не так с этим простым кодом scala?Складывание списка кортежей с помощью 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}

В других функциональных языках (например, F #) это работает:

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

ответ

12

Метод fold предполагает ассоциативный оператор и может в теории (например, при использовании параллелизма) выполняются в произвольном заказ. Таким образом, подпись становится ясно, что накапливающаяся тип должен быть супер-тип элемента в коллекции:

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

Inferred супер-тип (String, Int) и Int является Any.

Все это описано в статье API documentation.


То, что вы хотите это foldLeft или foldRight, которые не имеют этого ограничения на тип:

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

Поэтому:

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

или

(0 /: l) { 
    case (acc, (_, n)) => acc + n 
} 
Смежные вопросы