用存在类型进行类型推断 [英] Type inference with existential type
问题描述
我有一个通用特质 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屋!