简体   繁体   English

存在类型的类型推断

[英]Type inference with existential type

I have a generic trait SomeTrait defined as so: 我有一个通用特征SomeTrait定义为:

trait SomeTrait[T] {
  def foo(t: T): String
}

And methods bar and qux as so: 和方法barqux一样:

def bar[T](t: SomeTrait[T]): T
def qux: List[SomeTrait[_]]

I do not have control over the above. 我无法控制以上内容。 I am trying to operate on the list returned by qux , like so 我正在尝试对qux返回的列表进行操作,就像这样

qux map { x => x.foo(bar(x))}

However, the compiler complains that the types don't match up. 但是,编译器抱怨类型不匹配。 As far as I know this should be fine. 据我所知,这应该没问题。

I have tried adding a generic method (signature [T](SomeTrait[T])String ), and calling that to do the work, but the compiler still complains. 我尝试添加一个通用方法(签名[T](SomeTrait[T])String ),然后调用它来完成工作,但是编译器仍然抱怨。 I can cast my way around it like this: 可以这样处理:

qux map { x =>
  val casted = x.asInstanceOf[SomeTrait[T forSome { type T }]] // !!!
  casted.foo(bar(casted))
}

But this is even more perplexing, as x already has the type SomeTrait[_] and SomeTrait[T forSome { type T }] means the same thing. 但这更加令人困惑,因为x已经具有SomeTrait[_]类型和SomeTrait[T forSome { type T }]意味着同一件事。 The only difference that I'm aware of is that the former is a shorthand for the latter that makes the compiler create its own synthetic names. 我知道的唯一区别是,前者是后者的简写,后者使编译器创建自己的综合名称。 I'm hoping there's a better way to do this. 我希望有更好的方法可以做到这一点。 I have seen this question however I don't think it applies. 我已经看到了这个问题,但是我认为它不适用。

The correct way to do this is to use a type variable to give a name to T : 正确的方法是使用类型变量为T命名:

qux map { case x: SomeTrait[t] => x.foo(bar(x)) }

This way the compiler knows bar(x): t and so it's an acceptable argument to x.foo . 这样,编译器就知道bar(x): t ,因此它是x.foo的可接受参数。

Or, alternately, you can combine foo and bar into one method (remember that methods can be local, so you can just define it where you need it): 或者,也可以将foobar组合为一个方法(请记住,方法可以是局部的,因此您可以在需要的地方定义它):

def fooOfBar[T](x: SomeTrait[T]) = x.foo(bar(x))
qux map { fooOfBar(_) }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM