【问题标题】:Mapping between existential types存在类型之间的映射
【发布时间】:2015-10-17 12:00:38
【问题描述】:

我有几个这样的课程:

class Value[T]

class Container[T](v: Value[T], x: T)

现在我想将(Value[T], T)s 的序列转换为Container[T]s 的序列,其中序列中每个元素的T 可以不同。这种类型可以用existentials来表达:

def mapContainer(s: Seq[(Value[T], T) forSome {type T}]): Seq[Container[T] forSome {type T}]

但是,我似乎无法编写此函数的主体。我天真的尝试失败了:

def mapContainer(s: Seq[(Value[T], T) forSome {type T}]) =
    s.map(t => new Container(t._1, t._2))

错误如下所示:

[error]  found   : Value[T]
[error]  required: Value[Any]
[error] Note: T <: Any, but class Var is invariant in type T.

我不能使 Value 协变,无论如何这不是正确的解决方案,我相信。

话虽如此,我对结果类型 Seq[Container[_]] 也很好,但我也找不到获得它的方法。

是否可以不用asInstanceOf之类的方式来表达这一点?

【问题讨论】:

  • 您使用的是哪个版本的 Scala?它似乎适用于 2.11.7。至少,我没有收到任何错误。
  • 我认为你的mapContainer 定义(没有实现的那个)应该读起来有点不同,不是吗? def mapContainer(s: Seq[(Value[T], T)] forSome {type T}): Seq[Container[T]] forSome {type T}
  • 我使用的是 Scala 2.10.5。不,这个定义正是我的意思。 forSome 声明应该在inside括号内 - 否则它将要求序列的每个元素相同的类型
  • 哦,我现在明白了。第二个定义是无效的,当然我已经修好了。
  • 正如我所说,它适用于 2.11.7。是否可以选择更新的 Scala 版本?

标签: scala types existential-type


【解决方案1】:

解决方案:

重写

s.map(t => new Container(t._1, t._2))

s.map { case (v, x) => new Container(v, x) }

很遗憾,我无法解释为什么前者不起作用。

【讨论】:

  • 原因是擦除,s.map(t =&gt; new Container(t._1, t._2)) t._1 是 Value[T] 而t._2T。在s.map { case (v, x) =&gt; new Container(v, x) } vValue[Any]xAny,因为T 在比赛中被抹去。因此,mapContainer 函数的结果就是Container[Any]
猜你喜欢
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 2012-06-09
  • 2018-09-15
  • 1970-01-01
相关资源
最近更新 更多