2012-10-29 37 views
10

嘗試從chars列表生成映射到其頻率的唯一字符列表 - 例如,是這樣的:通過調用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)) 

但是,通過縮短剛剛過去的兩行合併不?

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

給出錯誤「missing parameter type」。

有人可以解釋爲什麼斯卡拉抱怨這種語法?

+0

,您可以用'myList.groupBy(身份).mapValues'(_大小。)完成您發佈的第一件事。 – Dylan

回答

19

當你說val s = l.toSet編譯器數字,唯一明智的類型toSetChar凹口 - 是最具體的選擇。然後,鑑於s是一組Char,編譯器意識到該映射必須來自Char

但是在第二種情況下,它對toSet中元素的類型是什麼進行了否定判斷。它可能是Char,但AnyVal也可以,Any也可以。

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

查看雷克斯對「爲什麼」部分的回答。 – Brian