Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala中的绑定存在类型_Scala_Collections_Existential Type - Fatal编程技术网

Scala中的绑定存在类型

Scala中的绑定存在类型,scala,collections,existential-type,Scala,Collections,Existential Type,这是我的基本CMap,它将类(任何T的类[T])映射到任何类型的值 scala> type CMap = Map[Class[T] forSome{type T}, Any] defined type alias CMap scala> val cMap: CMap = Map(classOf[Int]->5, classOf[String]->"abc", classOf[Double]->"ddd") cMap: CMap = Map(int -> 5,

这是我的基本CMap,它将类(任何T的类[T])映射到任何类型的值

scala> type CMap = Map[Class[T] forSome{type T}, Any]
defined type alias CMap

scala> val cMap: CMap = Map(classOf[Int]->5, classOf[String]->"abc", classOf[Double]->"ddd")
cMap: CMap = Map(int -> 5, class java.lang.String -> abc, double -> ddd)
现在我想要一个“绑定”的CMap(称之为CMapBind)。与CMap一样,它将类(任意类)映射到值(任意值)。但与CMap不同,CMapBind在键和值之间有一个类型绑定,这意味着我希望出现以下行为:

val cMapBind: CMapBind = Map(classOf[Int]->5, classOf[String]-> "aa") // should compile
val cMapBind: CMapBind = Map(classOf[Int]->5, classOf[String]-> 0)    // should fail compile
如何实现CMapBind

我知道以下两个在语法/逻辑上不起作用

scala> type CMapBind = Map[Class[T] forSome{type T}, T]
<console>:8: error: not found: type T
       type CMapBind = Map[Class[T] forSome{type T}, T]


scala> type CMapBind = Map[Class[T], T] forSome{type T}
scala> val cMapBind: CMapBind = Map(classOf[Int]->5, classOf[String]->"str")
<console>:8: error: type mismatch;
 found   : scala.collection.immutable.Map[Class[_ >: String with Int],Any]
 required: CMapBind
    (which expands to)  Map[Class[T],T] forSome { type T }
       val cMapBind: CMapBind = Map(classOf[Int]->5, classOf[String]->"str")
scala>type CMapBind=Map[Class[T]对于某些{type T},T]
:8:错误:未找到:类型T
类型CMapBind=Map[Class[T]对于某些{type T},T]
scala>type CMapBind=Map[Class[T],T]用于某些{type T}
scala>val-cMapBind:cMapBind=Map(classOf[Int]->5,classOf[String]->“str”)
:8:错误:类型不匹配;
找到:scala.collection.immutable.Map[Class[\u>:String with Int],Any]
必填项:CMapBind
(扩展为)映射[Class[T],对于某些{type T}
val cMapBind:cMapBind=Map(classOf[Int]->5,classOf[String]->“str”)
请注意,这里我使用类型构造函数类[T]作为示例来说明这个问题。在我的代码中,我有自己的类型,例如,
trait Animal[S,T],class Dog扩展Animal[Int,String]

编辑1:
我应该提到我正在使用不可变映射作为示例,但我真正需要的是一个可变的异构映射)。

让我们尝试实现可变的
HMap
。@milessbin对Scala类型系统的一些解释如下:

其思想是静态地检查构造函数(在这里您将看到,它的算术性取决于您的手,因此可以生成它或smth else)和insert方法。顺便说一句,同样的方法不可变
HMap
在shapeless中实现

import scala.collection.mutable.Map

class HMapBuilder[R[_, _]] { // constructor arity is two
  def apply[K1, V1](e1: (K1, V1))(implicit ev1: R[K1, V1]) = 
    new HMap[R](Map(e1))
  def apply[K1, V1, K2, V2](e1: (K1, V1), e2: (K2, V2))
                           (implicit ev1: R[K1, V1], ev2: R[K2, V2]) =
    new HMap[R](Map(e1, e2))
}
所以它是我们地图的构造器。证据将静态检查插入数据的类型。接下来,让我们包装默认的scala集合:

class HMap[R[_, _]](underlying : Map[Any, Any] = Map.empty) {
  def get[K, V](k : K)(implicit ev : R[K, V]) : Option[V] = 
    underlying.get(k).asInstanceOf[Option[V]]

  def +=[K, V](kv : (K, V))(implicit ev : R[K, V]) : HMap[R] = {
    underlying += kv
    this
  }
  def -=[K](k : K) : HMap[R] = {
    underlying -= k
    this
  }

  override def toString = underlying.toString
}
最后包装
HMapBuilder
,以创建一个令人愉快的构造函数:

object HMap {
  def apply[R[_, _]] = new HMapBuilder[R]

  def empty[R[_, _]] = new HMap[R]
  def empty[R[_, _]](underlying : Map[Any, Any]) = 
    new HMap[R](underlying)
}
因此,该用法类似于
无形状
HMap

class Mapping[K, V]

implicit def mappingFromClass[A] = new Mapping[Class[A], A]

val hm = HMap[Mapping](classOf[Int] -> 5) // ok
hm += (classOf[String] -> "string") // ok
hm += (classOf[Boolean] -> false) // ok
hm += (classOf[Double] -> "sss") // compile fail    

一切正常。我只实现了插入和删除函数,其他函数也可以用同样的方式定义。

请参阅“由于类型擦除,无法确定是否可以(以您希望的方式)执行”。此映射将始终松开值类型(到上限
Any
),键类型将始终混合。我想你需要一种异构的
Map
,来保存类型。是的,像
shapeless
中的
HMap
这样的异构映射是我要看的。你不可能使用shapeless,你想用你自己的吗?因为使用shapeless非常好:)如果可以的话,我很乐意使用
shapeless
HMap
。在我的应用程序中,我需要一个“可变”的异构映射。我的理解是
HMap
是不可变的。