简体   繁体   English

调用toSet是否缺少参数类型错误?

[英]Missing parameter type error by calling toSet?

Trying to generate, from a list of chars, a list of unique chars mapped to their frequency - eg 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? 但是,仅通过组合最后2行缩短不?

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? 有人可以解释为什么Scala会抱怨这种语法吗?

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. 当你说val s = l.toSet编译器数字,唯一明智的类型toSetChar凹口-是最具体的选择。 Then, given that s is a set of Char , the compiler realizes that the map must be from a Char . 然后,假设s是一组Char ,编译器意识到映射必须来自Char

But in the second case, it withholds judgment on what the type of elements in toSet is. 但在第二种情况下,它拒绝判断toSet的元素类型是什么。 It might be Char , but AnyVal would also work, as would Any . 它可能是Char ,但AnyVal也可以, 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. 但是由于函数在它们的参数中是逆变的,所以当它们将Any作为参数时它们是最具体的,因此编译器无法决定。 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: 您可以在函数参数或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))

Adding the type [Char] to toSet does the trick. 将类型[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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM