用存在类型进行类型推断 [英] Type inference with existential type

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

问题描述

我有一个通用特质 SomeTrait 定义为:

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

bar qux 如下:

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

我无法控制上述内容。我试图在由 qux 返回的列表上操作,就像这样

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

然而,编译器抱怨这些类型没有配对。据我所知,这应该没问题。

我尝试添加一个泛型方法(签名 [T](SomeTrait [T])String ),然后调用它来完成这项工作,但编译器仍然抱怨。

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

但这是因为 x 已经有类型 SomeTrait [_] SomeTrait [T forSome {type T}] 表示同样的事情。我知道的唯一区别是前者是后者的缩写,它使编译器创建自己的合成名称。我希望有更好的方法来做到这一点。我已经看过这个问题,但我认为它不适用。

解决方案

正确的方法是使用一个类型变量来命名 T

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

这样编译器知道 bar(x):t ,因此它是 x.foo 的可接受参数。



<或者,也可以将 foo bar 结合到一个方法中(请记住,方法可以是局部的,所以你可以在需要的地方定义它):

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


I have a generic trait SomeTrait defined as so:

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

And methods bar and qux as so:

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 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. 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. 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:

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.

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):

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

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

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