Missing parameter type error by calling toSet?

scala, type-inference

Solution

When you say `val s = l.toSet` the compiler figures that the only sensible type for `toSet` is `Char`--that's the most specific choice. Then, given that `s` is a set of `Char`, the compiler realizes that the map must be from a `Char`.

But in the second case, it withholds judgment on what the type of elements in `toSet` is. It might be `Char`, but `AnyVal` would also work, as would `Any`.

l.toSet.map((i: Any) => (i, l.filter(x => x == i).size))

Normally the rule is that the compiler should pick the most specific value. But since functions are contravariant in their argument, they are most specific when they take an `Any` as an argument, so the compiler can't decide. There could exist a rule to break the tie ("prefer the early assumption"), but there isn't one implemented. So it asks for your help.

You can provide the type either on the function argument or on the `toSet` to fix the problem:

l.toSet.map((i: Char) => (i, l.filter(x => x == i).size))
l.toSet[Char].map(i => (i, l.filter(x => x == i).size))

Problem

Trying to generate, from a list of chars, a list of unique chars mapped to their frequency - e.g. something like: ``` List('a','b','a') -> List(('a',2), ('b',1)) ``` So, just mucking around in the console, this works: ``` val l = List('a', 'b', 'c', 'b', 'c', 'a') val s = l.toSet s.map(i => (i, l.filter(x => x == i).size)) ``` but, shortening by just combining the last 2 lines doesn't? ``` l.toSet.map(i => (i, l.filter(x => x == i).size)) ``` gives the error "missing parameter type". Can someone explain why Scala complains about this syntax?

Original source