2013-10-08 31 views
3

有时,编码地图中键和值类型之间的依赖关系可能很有用。考虑以下类型:Scala中的Map键和值类型参数之间的依赖

type MyPairs = Seq[(TypeTag[T], T) forSome {type T}] 

这里每对的序列中应当具有相同的类型T。但是这种类型在地图使用方面不是很方便。然而,我不能表达这种依赖关系Map[K, V],因为Map有两个独立的类型参数,并且我似乎无法以任何方式“组合”它们来使用单个存在类型。天真的变体

type MyMap = Map[TypeTag[T], T] forSome {type T} 

只是强制单一类型T。对于所有MyMap条目,但不是单独针对每个条目。

另一个极端,我认为,是

type MyMap = Map[TypeTag[_], _] 

但这是,当然,过于宽泛的定义,允许键值类型的任意组合。

所以我的问题是,有可能在Scala中编码这种类型?如果是,如何?

+0

同时http://stackoverflow.com/questions/7401329/map-from-classtto-t-without-casting;也http://stackoverflow.com/questions/7038708/scala-existential-types-for-a-map –

+0

@ 0__,谢谢。看起来我的搜索技能有点缺乏...... –

回答

0

正如其他人指出的那样,您需要使用异构映射。横七竖八的项目有一个这样的实现:

https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-1.2.4#heterogenous-maps

这可以让你做的事:

import shapeless._ 
class Constrainer[K, V] 
implicit def allowed[T] = new Constrainer[Class[T], T] 
val hmap = HMap[Constrainer](classOf[String] -> "Hi there", classOf[Int] -> 3) // this compiles 
val hmapFail = HMap[Constrainer](classOf[String] -> 3) // this won't compile 

针对您的特殊例如使用TypeTag的:

import shapeless._ 
import scala.reflect.runtime.universe._ 
class Constrainer[K, V] 
implicit def allowed[T] = new Constrainer[TypeTag[T], T] 
val hmap = HMap[Constrainer](typeTag[String] -> "hello", typeTag[Int] -> 2) // this compiles 
val hmapFail = HMap[Constrainer](typeTag[String] -> 3) // this won't compile 

注意,您可以使用一个隐含的值(或者在我们的例子中的转换)来规定允许(键,值)对的哪些实例。