映射存在类型列表 [英] Mapping over a list of existential types

查看:78
本文介绍了映射存在类型列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个要映射的存在类型的对象列表.像这样:

I have a list of existientially-typed objects I want to map over. Something like this:

sealed abstract class IntBox(val v: Int)
case object IB1 extends IntBox(1)
case object IB2 extends IntBox(2)

case class Adder[A  <: IntBox](ib: A, v: Int) {
  def add(i: A) = v + i.v
}

val adders: List[Adder[_ <: IntBox]] = List(Adder(IB1, 0), Adder(IB2, 0))

adders.map(adder => adder.add(adder.ib))

但是,我遇到了类似的错误

However, I'm getting an error like

found: adder.ib.type
required: _$1

我觉得这是因为map以某种方式将不同的IntBox统一为一种无法获得的匿名类型...

I feel it's something like because the map somehow unifies the different IntBoxs into one unobtainable anonymous type...

我可以在不强制转换的情况下得到想要的东西吗(即adder.asInstanceOf[Adder[adder.ib.type]]...?

Can I get what I want without casting (i.e. adder.asInstanceOf[Adder[adder.ib.type]]...?

推荐答案

类型不是不可获取的,您可以使用类型模式匹配来获取它:

The type is not unobtainable, you can get it using type pattern matching:

adders.map{ case a: Adder[t] => a.add(a.ib) }

在这里,存在性类型参数绑定到类型变量t,并且编译器可以正确地推断出无法为整个列表推断的t附加属性.

Here, the existential type parameter is bound to type variable t, and the compiler can correctly infer additional properties of t that it cannot infer for the whole list.

请参阅 8.3部分.规范1 .

class替换为trait的完整代码以使其编译

Full code with trait replaced by class to make it compile

sealed abstract class IntBox(val v: Int)
case object IB1 extends IntBox(1)
case object IB2 extends IntBox(2)

case class Adder[A  <: IntBox](ib: A, v: Int) {
  def add(i: A) = v + i.v
}

val adders: List[Adder[_ <: IntBox]] = List(Adder(IB1, 0), Adder(IB2, 0))

adders.map{ case a: Adder[t] => a.add(a.ib) }

这篇关于映射存在类型列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆