如何使 Scala 类型推断足够强大以发现泛型类型参数? [英] How to make Scala type inference powerful enough to discover generic type parameter?
问题描述
假设我定义了一个采用隐式 TypeTag 的函数:
Assuming that I defined a function that takes implicit TypeTag:
def andOptionFn[A: TypeTag](g: Int => Option[A]) = {
val ttg = ScalaReflection.universe.typeTag[A]
println(ttg)
...
}
并调用它:
andOptionFn{
v =>
Some(v)
}
我希望 Scala 类型推断能够获得正确的类型 TypeTag(Option(Int)),但我得到了:
I would expect scala type inference to get the correct type TypeTag(Option(Int)), but instead I got:
TypeTag(Option(Any)) (not even a higher kind)
为什么Scala无法在编译时自动推断?以及需要做哪些工作来改进它?
Why Scala is unable to infer it automatically in compilation time? and what works needs to be done to improve it?
推荐答案
正确的结果是 TypeTag[Int]
,Scala 确实打印了它:http://scastie.org/20273(在您将 ScalaReflection
替换为 scala.reflect.runtime
之后;如果ScalaReflection
是你自己的类,那是你应该寻找问题的地方).
The correct result is TypeTag[Int]
, and Scala does print it: http://scastie.org/20273 (after you replace ScalaReflection
with scala.reflect.runtime
; if ScalaReflection
is your own class, that's where you should look for the problem).
http://scastie.org/20293 不是错误,而是类型推断的准确行为按照设计.对 Seq.apply[Option[_]]
的调用为每个参数提供了 Option[_]
的预期类型.什么时候
http://scastie.org/20293 isn't a bug, it's type inference behaving precisely as designed. Call to Seq.apply[Option[_]]
gives the expected type of Option[_]
to each argument. When
andOptionFn {
v =>
if (v > 1) Some(v)
else None
}
使用这种预期类型进行类型检查,推断出的R
当然是Any
.
is typechecked with this expected type, the inferred R
is of course Any
.
编辑 2:阅读 http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#local-type-inference 更仔细,它似乎应该推断 Int
毕竟,但我不确定.我认为 Option[_]
被简化为 Option[Any]
(因为 Option
是协变的),在这种情况下 Any
肯定应该被推断出来.但是 http://scastie.org/20293 和 http://scastie.org/20295 应该表现相同,所以至少有一个错误(我认为):)
EDIT 2: After reading http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#local-type-inference more carefully, it does seem like it should infer Int
after all, but I am not certain. What I thought is that Option[_]
gets reduced to Option[Any]
(because Option
is covariant), in which case Any
should certainly be inferred. But http://scastie.org/20293 and http://scastie.org/20295 should behave the same, so there is at least one bug (I think) :)
这篇关于如何使 Scala 类型推断足够强大以发现泛型类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!