Scala中Map键和值类型参数之间的依赖关系

时间:2013-10-08 14:17:31

标签: scala types map existential-type parametric-polymorphism

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

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中编码这样的类型吗?如果是,怎么样?

1 个答案:

答案 0 :(得分:1)

正如其他人所指出的,你需要使用异质地图。无形的项目实现了这个:

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

请注意,您可以使用隐式值(或我们的情况下的转换)来指示允许(键,值)对的实例。