Something about implicit class, confuses reduce(). When inside implicit class, compiler complains on reduce() second parameter. but when same code is inside non-implicit method it compiles and works fine.
What am I missing about implicit classes?
object ImpliCurri {
implicit class MySeq[Int](val l: Seq[Int]) {
//not compiling
final def mapSum(f:Int=>Int):Int = {
l.map(x=>f(x)).reduce(_+_)
//compile error on reduce: Type mismatch. Expected String, fount Int
}
}
// works fine
def mySum(l:Seq[Int], f:Int=>Int):Int = {
l.map(x=>f(x)).reduce(_+_)
// compiles and works no issues
}
}
It doesn't actually have anything to do with implicits. You get the same error if it's just a regular class
.
The reason is that you have declared a generic type: MySeq[Int]
that just happens to be called Int
. So when you say f: Int => Int
you think "Oh, that's an integer" and the compiler thinks, "Oh, that means you could fill in any type there!". (Replace all your Int
s with A
and it would work the same.)
Now the compiler is in a bind. What +
can you apply to any pair of types? Well, you can convert anything to a String
, and +
is defined on a String
. So you get a very misleading error message when the compiler realizes that this approach won't work.
Just drop the [Int]
and all your Int
s will actually mean what you think they mean, and the implicit class version will work fine.