I am learning Scala and I'm having some troubles to write a simple reducer function. I want to count how many times a value appear in a list. Thus, I wrote a reducer/folding function which takes an immutable map as initial value, and then iterates the list "updating" the map with the number of times a value appears in the list. Quite simple stuff, but I am having an issue with the type system (Ahhh... too much time spent on JavaScript and Python)
This is the function:
def times(chars: List[Char]): List[(Char, Int)] = {
val acc:Map[Char, Int] = Map()
def count(acc:Map[Char, Int], c:Char) = {
if (acc contains c) acc + (c -> (acc(c) + 1))
else acc + (c -> 1)
}
chars.fold(acc)(count).toList
}
I can't understand why I am getting the following type error :
[error] /Users/giuseppe/courses/scala_functional_programing/lessons/week_4/assignment/src/main/scala/patmat/Huffman.scala:85: type mismatch;
[error] found : (Map[Char,Int], Char) => scala.collection.immutable.Map[Char,Int]
[error] required: (Any, Any) => Any
[error] chars.fold(acc)(count)
[error] ^
[error] /Users/giuseppe/courses/scala_functional_programing/lessons/week_4/assignment/src/main/scala/patmat/Huffman.scala:85: type mismatch;
[error] found : Any
[error] required: List[(Char, Int)]
[error] chars.fold(acc)(count)
[error] ^
[error] two errors found
Is Map[Char, Int]
a subtype of Any
?
* EDIT *
Even more interesting, I've just discovered that if I use foldLeft
, it works properly. :confused: Why??
Any help would be really appreciated. Thank you
It's looks like you need foldLeft function instead of fold. It has proper signature.
def foldLeft[B](z: B)(f: (B, A) => B): B = { // in your case B is Map and A is Char
def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op) // in your case arguments of count functions should be same
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.