2013-02-20 123 views
1

我有一個對其類型參數協變的Container類型。返回具有協變類型的immutable.Map

class Container[+T](val map: Map[Int, T] = Map.empty[Int, T]){ 
    def add[B >: T](i: Int, b: B) = new Container(map + (i->b)) 
// lazy val freqs = (map.toList groupBy (x=>x._2) mapValues(_.size)) 
// lazy val uniq = map.toSet 
     lazy val keySet = map.keySet 
    } 

我在想,我得到的錯誤嘗試與freqs或uniq的註釋掉編譯的原因有什麼Spiewak先生在他的答案寫在這裏做的,那Set S和Map s爲在相關參數不變。

Why is Scala's immutable Set not covariant in its type?

不過我有點驚訝地發現,這是沒有問題的,包括它的keySet不會返回一個Set,其類型爲T.

我能夠部分通過寫

解決此
lazy val freqs:Map[_ <: Any, Int] = 
    (map.toList groupBy (x=>x._2) mapValues(_.size)) 

但是這並不理想,因爲密鑰類型出現爲Any。我希望能夠還說

lazy val uniqueValues = freqs.keySet 

,並獲得Set[T]代替Set[Any]

  • 我怎樣才能最好地實現freqs如上?
  • keySet在其他方法失敗時如何返回Set [T]?
  • 如何在Map中獲得唯一值的Set[T]
  • 爲什麼_ <:任何允許這個編譯?

謝謝!

+0

就好像'Map'是落後的。知道頻率都是不同的? – 2013-02-20 23:54:06

+0

提到了兩張地圖,都不是落後的。第一個Map是Container參數,一個Map [Int,T]:每個Int是T的別名。第二個map是freqs的返回類型,Map [T,Int]是別名數的計數對於每個T. – scalapeno 2013-02-21 00:12:07

回答

3

不過我有點驚訝地發現,這是沒有問題的,包括它的keySet不返回一組,其型號爲T

不,它不需要。 map的類型爲Map[Int, T],因此其的類型爲T,其的類型爲Int。所以keySet這裏的類型是Set[Int](和而不是Set[T]),這意味着T的協方差沒有問題。

當其他方法失敗時,keySet如何返回Set [T]?

它不(見上文)

我怎樣才能在地圖獲得唯一值的設定[T]?

鑑於Set在其類型參數不變的,根本就沒有辦法有Set[T]類型的任何VAL內Container,除非您將這些丘壑爲private[this],或者使Container不變的T

如何才能最好地實現上述頻率?

與上述相同的問題。

爲什麼_ <:任何允許這個編譯?

因爲,明確指出freq類型爲Map[_ <: Any, Int]你刪除的任何依賴於T,因而不存在問題,只要方差有關時。如果你沒有明確說明freq的類型,scala(正確)推斷類型爲Map[T, Int],其中確實是依賴於T處於不變位置。

+0

感謝您的建議,但添加私人[這]似乎沒有幫助。 (add)[B>:T](i:Int,b:B)= new();}} {Container {[T]容器(地圖+(i-> b)); private [this] lazy val freqs =(map.toList groupBy(x => x._2)mapValues(_。size)) } – scalapeno 2013-02-21 00:32:36

+0

您正在使用哪個版本的scala,您可以嘗試更新一? – 2013-02-21 00:47:22

+0

我檢查過它,確實它在scala 2.10中工作,但不在scala 2.9中。顯然,在具有'private'[this]'val'type'T'的scala 2.9中可以工作,但是如果將類型更改爲在T中不變的類(而不是簡單**爲** T)例如'Set [T]',它不再工作。這看起來像我的一個Scala 2.9的bug。 – 2013-02-21 08:15:30