Let's say I have an empty mapval map = Map[Int, Int]()
I'm confused because while the following code compiles properly:
map.foldLeft((0,0)){case((k1, v1), (k2, v2)) => (-1, -1)}
the following, seemingly exact code snippet results in compilation error:
map reduceLeft {case((k1, v1), (k2, v2)) => (-1, -1)}
The error is:
scala> map reduceLeft {case((k1, v1), (k2, v2)) => (k1, v1)}
<console>:9: error: missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: (?, (Int, Int)) => ?
map reduceLeft {case((k1, v1), (k2, v2)) => (k1, v1)}
It's not a huge problem, but obviously it would be nice to not have to deal with this. Do you have any ideas on what could I do differently, or do I just have to learn to accept it?
The reason this happens is that foldLeft
has two parameter lists (the 1st being the initial, "priming" value and 2nd being the function) and reduceLeft
has only one (the function).
Scala's type inference operates one parameter list at a time. Additionally, types inferred in one parameter list are available to guide or constrain type inference in later ones (those further right) in ways they cannot help guide or constrain type inference within a given parameter list. In this case, Scala cannot infer properly the B type in the reduceLeft
signature:
def reduceLeft[B >: (A, B)](op: (B, (A, B)) ⇒ B): B
While in the fold case:
def foldLeft[B](z: B)(op: (B, (A, B)) ⇒ B): B
it binds a type to B by looking at your primer value alone ((0, 0)
) which it then has available to infer the parameter types in the function (without you making them explicit).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With