【发布时间】:2021-08-23 10:25:10
【问题描述】:
使用 Scala 2.13.5,我正在尝试实现一个存储某种简单类型值的表。 (我真正感兴趣的是毛茸茸的,但简单的版本说明了我的问题。)
import scala.collection.immutable.HashMap
class ListMap[K] private[ListMap] (hm: HashMap[K, List[K]]) {
def put[V1 <: K, V2 <: List[K]](k: V1, x: V2
)(implicit ev: V2 =:= List[V1]):
ListMap[K] = {
new ListMap[K](hm + ((k -> x)))
}
def get[V1 <: K](x: V1): Option[List[V1]] = hm.get(x)
}
object ListMap {
def make[K] = new ListMap[K](new HashMap[K, List[K]]())
}
这个想法是,您可能有一个 ListMap[Any],其中包含 3 -> List(2,2) 和 "abc" -> List("foo", "bar") 等条目。存储的值是与键相同类型的对象列表。
代码无法编译。错误信息是
...error: type mismatch;
found : Option[List[K]]
required: Option[List[V1]]
def get[V1 <: K](x: V1): Option[List[V1]] = hm.get(x)
更改get 的定义使其返回类型为Option[List[K]] “解决”了问题。
然而,put 函数实际上保证了更强的属性,即为给定的x 类型的V1 存储的值是List[V1]。我已经对这个问题进行了足够长时间的努力,以至于我确信它只是超出了 Scala 类型系统的能力。我对吗?有没有办法告诉类型系统:相信我,值的类型是List[V1]?如果我知道如何将其转换为我想要的类型声明,我愿意对找到的列表进行冗余测试以验证其每个元素是否满足某个谓词。
【问题讨论】: