missing parameter type error by calling toSet
scala
Solution
First, there's a simpler version of the code that has the same issue:
List('a', 'b', 'c').toSet.foreach(e => println(e))
This doesn't work either
List('a', 'b', 'c').toBuffer.foreach(e => println(e))
However, these work just fine:
List('a', 'b', 'c').toList.foreach(e => println(e))
List('a', 'b', 'c').toSeq.foreach(e => println(e))
List('a', 'b', 'c').toArray.foreach(e => println(e))
If you go take a look at the `List` class documentation you'll see that the methods that work return some type parameterized with `A`, whereas methods that don't work return types parameterized with `B >: A`. The problem is that the Scala compiler can't figure out which `B` to use! That means it will work if you tell it the type:
List('a', 'b', 'c').toSet[Char].foreach(e => println(e))
Now as for why `toSet` and `toBuffer` have that signature, I have no idea...
Lastly, not sure if this is helpful, but this works too:
// I think this works because println can take type Any
List('a', 'b', 'c').toSet.foreach(println)
Update: After poking around the docs a little bit more I noticed that the method works on all the types with a covariant type parameter, but the ones with an invariant type parameter have the `B >: A` in the return type. Interestingly, although `Array` is invariant in Scala they provide two version of the method (one with `A` and one with `B >: A`), which is why it doesn't have that error.
I also never really answered why breaking the expression into two lines works. When you simply call `toSet` on its own, the compiler will automatically infer `A` as `B` in the type for the resulting `Set[B]`, unless you do give it a specific type to pick. This is just how the type inference algorithm works. However, when you throw another unknown type into the mix (i.e. the type of `e` in your lambda) then the inference algorithm chokes and dies—it just can't handle an unknown `B >: A` and an unknown type of `e` as well.
Problem
Why this code doesn't work: ``` scala> List('a', 'b', 'c').toSet.subsets.foreach(e => println(e)) <console>:8: error: missing parameter type List('a', 'b', 'c').toSet.subsets.foreach(e => println(e)) ^ ``` But when I split it then it works fine: ``` scala> val itr=List('a', 'b', 'c').toSet.subsets itr: Iterator[scala.collection.immutable.Set[Char]] = non-empty iterator scala> itr.foreach(e => println(e)) Set() Set(a) Set(b) Set(c) Set(a, b) Set(a, c) Set(b, c) Set(a, b, c) ``` And this code is OK as well: ``` Set('a', 'b', 'c').subsets.foreach(e => println(e)) ```