2015-05-06 40 views
1

給定一個(數據結構像a一樣操作)Map。有沒有類型級的插入方式?那就是:類型級別在斯卡拉的地圖上插入和檢索特定值

val myMap: Map[Int, String] = Map(1 -> "a", 2 -> "b") 
val x: Int = 5 
val y: Int = 99 

val myMap2 = myMap + (x -> "e") 

什麼我希望的是,myMap2將有一些類型,其中,我可以放心地做這樣的事情myMap2.retrieve(x),並把它編譯並返回"e"。但是myMap2.retrieve(y)甚至不應該編譯。

回答

1

有可能與Shapeless,如果你的鍵有不同的類型:

import shapeless._ 

object _1 
object _2 
object _3 
object _4 


//-------------Map definition starts here---------------- 
class StaticMap1[K, V] 
trait StaticMap1Like { 
    type M[T] <: StaticMap1[T, String] 
    private def add[T]: M[T] = (new StaticMap1[T, String] {}).asInstanceOf[M[T]] 

    implicit val __1 = add[_1.type] //add key to StaticMap1 
    implicit val __2 = add[_2.type] //add key to StaticMap1 
} 
object StaticMap1 extends StaticMap1Like 


val hm = HMap[StaticMap1](_1 -> "a", _2 -> "b") //add values 
//-------------Map definition ends here----------------- 

scala> hm.get(_1) 
res0: Option[String] = Some(a) 

scala> hm.get(_2) 
res1: Option[String] = Some(b) 

scala> hm.get(_3) //compile-time error 
<console>:18: error: could not find implicit value for parameter ev: BiMapIS[shapeless.nat._3,V] 
       hm.get(_3) 
        ^

和密鑰插入:

//----Adding element _3 -> "c" starts here-------------- 
class StaticMap2[K, V] extends StaticMap1[K, V] 
trait StaticMap2Like extends StaticMap1Like { 
    type M[T] <: StaticMap2[T, String] 
    private def add[T] = new StaticMap2[T, String] {}.asInstanceOf[M[T]] 
    implicit val __3 = add[_3.type] //add key to StaticMap2 
} 
object StaticMap2 extends StaticMap2Like 

val hm2 = hm.asInstanceOf[HMap[StaticMap2]] + (_3 -> "c") 
//----Adding element ends here--------------------------- 

scala> hm2.get(_3) 
res6: Option[String] = Some(c) 

scala> hm2.get(_2) 
res7: Option[String] = Some(b) 

scala> hm2.get(_1) 
res8: Option[String] = Some(a) 

scala> hm2.get(_4) 
<console>:21: error: could not find implicit value for parameter ev: StaticMap2[_4.type,V] 
      hm2.get(_4) 
       ^

scala> hm.get(_3) //old `hm` still working 
<console>:17: error: could not find implicit value for parameter ev: StaticMap1[_3.type,V] 
      hm.get(_3) 
       ^

但是:

  • 不使用無形本地nat這裏 - 它不會工作,因爲它不能區分nat._1nat._2(至少對於我的版本無形的)
  • 添加元素аMap也不會這麼方便易,因爲用戶會不得不增加一個隱含的每一個新的關鍵
0

每次使用myMap2.get(y)時,如果是Int,您將得到任何y的字符串Option。 如果您嘗試使用任何其他類型,您將遇到編譯異常。 例如:myMap2.get("y")會拋出類型不匹配。 所以你不能編譯,如果密鑰類型不是正確的。