2012-10-29 9 views
10

文字のリストから、その周波数にマッピングされた一意の文字のリストを生成しようとしています。toSetを呼び出すとパラメータタイプのエラーが表示されますか?

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)) 

しかし、ちょうど最後の2行をしない組み合わせることにより、短縮?

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

には、「パラメータタイプがありません」というエラーが表示されます。

Scalaがこの構文について不平を言う理由を説明する人はいますか?

+0

をちょうどFYIは、 '' myList.groupBy(アイデンティティ).mapValues(。_サイズ)を使用することができますあなたが投稿した最初のものを達成する。 – Dylan

答えて

19

あなたはval s = l.toSetコンパイラはtoSetのための唯一の賢明なタイプが最も具体的な選択です--that Charであることを数字と言います。次に、sCharのセットであるとすれば、コンパイラはマップがCharでなければならないことを認識します。

しかし、第2のケースでは、toSetの要素のタイプが何であるかの判断を保留します。それはCharかもしれませんが、Anyと同様にAnyValも機能します。

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

通常、コンパイラは最も特定の値を選択する必要があります。しかし、関数は引数に反例があるので、引数としてAnyを取るときに最も具体的であるため、コンパイラは決定できません。同調を破るルールが存在する可能性がある(「初期の仮定を優先する」)が、実装されていない。それであなたの助けを求める。あなたが問題を解決するために、関数の引数や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)) 
+1

きちんと説明してくれてありがとう。 –

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)) 
+3

ありがとうございます。そのようなことは、最初の例でそのタイプ情報を提供しなかったので、質問を「なぜ」にプッシュします。 –

+0

「理由」の部分についてRexの答えを参照してください。 – Brian

関連する問題