【问题标题】:Map with path-dependent value type?具有路径相关值类型的映射?
【发布时间】:2015-06-10 18:52:58
【问题描述】:

我知道 Scala 具有依赖于路径的类型,因此例如,如果我在内部类中有一个类,我可以将方法的一个参数限制为另一个参数的内部类的实例:

class Outer { class Inner( x:Int ) }
val o1 = new Outer
val o2 = new Outer
val i11 = new o1.Inner(11)
val i12 = new o1.Inner(12)
val i21 = new o2.Inner(21)
def f[ A <: Outer ]( a:A )( i:a.Inner ) = (a,i)
f(o1)(i11)  // works
f(o1)(i21)  // type mismatch; i21 is from o2, not o1

我可以使用类型投影创建从外部到内部的地图:

var m = Map[Outer,Outer#Inner]()

但这将允许像o1 -&gt; i21 这样的条目,我不希望这样。是否有任何类型的魔法要求一个值是其键的内部类的实例?也就是说,我想说类似

var m = Map[Outer,$1.Inner]()  // this doesn't work, of course

【问题讨论】:

  • 您对问题的表述方式:“要求该值是键的内部类的实例”已经描述了您的var m = Map[Outer,Outer#Inner]()
  • def g[A &lt;: Outer] = Map.empty[A, A#Inner]
  • 我认为类型系统在这里不会帮助你(除非你像 Shapeless 的 HMap 这样的路线),但你总是可以监督添加到地图中的内容。
  • 你需要一个新的、更受约束的 Map 类型或 Scala 中的任意依赖类型。前者您可以将其编写为现有Map 的安全包装器。您基本上只能通过键类型对其进行参数化,并限制键具有一些命名的内部类型,然后您的访问器方法将具有类似def get(k: K): k.Inner 的类型。它不会实现当前的 Scala 集合通用地图特征。

标签: scala map path-dependent-type


【解决方案1】:

没有。

路径相关类型的范围是一个对象实例,如您给出的示例中所示:

def f[ A <: Outer ]( a:A )( i:a.Inner ) = (a,i)

这里依赖路径的类型依赖于对象引用“a”,它在第二个参数列表的声明范围内。

map definition 有点像:

trait Map[A,+B] {
  def get(key: A): Option[B]
  def + [B1 >: B](kv: (A, B1)): This
}

这里没有A 类型的对象供您在定义B 时参考。

正如其他人所暗示的,您可以定义一个符合此要求的新的类似 Map 类:

trait Map2[A <: Outer] {
  def get(key: A): Option[key.Inner]
  def put(key: A)(value: key.Inner): this.type
}

【讨论】:

  • Travis 和 Dan 实际上在大约一年半前通过 cmets 为我回答了这个问题,但对于未来的读者来说,很高兴有一个更清楚地解释事情的实际答案,所以我会接受这个作为答案,Rich。
猜你喜欢
  • 1970-01-01
  • 2019-02-26
  • 2017-04-04
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 2012-05-12
  • 2016-10-13
  • 2012-03-04
相关资源
最近更新 更多