14

尝试从字符列表中生成映射到其频率的唯一字符列表 - 例如:

List('a','b','a') -> List(('a',2), ('b',1))

因此,只需在控制台中乱搞,就可以了:

val l = List('a', 'b', 'c', 'b', 'c', 'a')       
val s = l.toSet                                  
s.map(i => (i, l.filter(x => x == i).size))

但是,仅通过组合最后两行来缩短不是吗?

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

给出错误“缺少参数类型”。

有人可以解释为什么 Scala 抱怨这种语法吗?

4

2 回答 2

24

当您说val s = l.toSet编译器认为唯一合理的类型toSetChar-- 那是最具体的选择。然后,鉴于这s是一组Char,编译器意识到映射必须来自Char

但在第二种情况下,它拒绝判断元素的类型是什么toSet。它可能是Char,但AnyVal也会像 一样工作Any

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

通常规则是编译器应该选择最具体的值。但是由于函数的参数是逆变的,所以当它们以 anAny作为参数时它们是最具体的,因此编译器无法决定。可能存在打破平局的规则(“更喜欢早期假设”),但没有实施。所以它需要你的帮助。

您可以在函数参数或toSet解决问题的方法上提供类型:

l.toSet.map((i: Char) => (i, l.filter(x => x == i).size))
l.toSet[Char].map(i => (i, l.filter(x => x == i).size))
于 2012-10-29T21:45:49.813 回答
3

添加类型 [Char] 就toSet可以了。

scala> l.toSet[Char].map(i => (i, l.filter(x => x == i).size))
scala.collection.immutable.Set[(Char, Int)] = Set((a,2), (b,2), (c,2))
于 2012-10-29T21:39:29.913 回答