I'm following the excellent Functional Programming in Scala by Paul Chiusano and Rúnar Bjarnason, and had a question to what I find is odd/unexpected behaviour.
I have defined a foldRight function like so
def foldRight[A,B](l: List[A], z: B)(f: (A,B) => B): B =
l match {
case Nil => z
case x :: xs => f(x, foldRight(xs, z)(f))
}
that works fine as long I pass in concrete arguments, e.g.:
foldRight((1 to 10).toList, 0)(_ + _)
val res6: Int = 55
If I define a similar function that takes the generic list
def sum[A](as: List[A]): Int = foldRight(as, 0)(_ + _)
something odd happens
def sum[A](as: List[A]): Int = foldRight(as, 0)(_ + _)
^
fold.scala:23: error: type mismatch;
found : Int
required: String
Initially, I was super puzzled by this error message given the only types in play are A, B and Int. However, would seem it simply attempts to make sense of + and generic A's by calling .toString on them as I read about here.
If that is the case though, why come it doesn't simply adds a1.toString + a2.toString + ... + an.toString + 0 = something0? String concatenation between String and Int in Scala is fully understood by the compiler.
Hope someone can help clarifying what's happening here.
A? What if I give you a List of Maps of Users? That should give you an idea of what is wrong. Now, for the specific error message(_ + _)is expanded as(x: A, y: Int) => x + y, since we do not know anything of A all we can assume is that is has the same methods of Any, which does has a+method (due freaking Java) which also takes an Any and returns an String. Sox + ygives an String, but the compiler expected a function from(A, Int) => Int, thus the error.+methodnull, or you may never get an actual value to call the methods, like with Nothing). Also, I believe there is an implicit conversion from A to Any always in scope.