【问题标题】:In Scala, how to circumvent 'inferred type arguments do not conform' error?在 Scala 中,如何规避“推断类型参数不符合”错误?
【发布时间】:2016-06-18 19:57:31
【问题描述】:

我有一个带有隐式 TypeTag 参数的反射函数:

def fromOptionFn[R: TypeTag](self: Int => Option[R]): Wrapper[R] = {
println(TypeTag[R])
...
}

由于未知原因不起作用(请参阅How to make Scala type inference powerful enough to discover generic type parameter?):

> fromOptionFn2(v => Some(" + _))
> typeTag(Any)

我推测它是由 Option[R] 推断 R 引起的,所以我稍微改进一下:

def fromOptionFn[R, Opt <: Option[R]: TypeTag](self: Int => Opt): Wrapper[R] = {
println(typeTag[Opt])
...
}

这次更糟糕,甚至没有编译,错误清楚地推断出scala不够聪明,无法分析类型:

> fromOptionFn2(v => Some(" + _))
Error: inferred type arguments [Nothing,Option[String]] do not conform to method fromOptionFn's type parameter bounds [R,Opt <: Option[R]]

那么我该如何暂时规避这个编译问题呢? (当然我可以在 Lightbend 问题跟踪器上报告它,但它太慢了)

附录:这个问题本身是对How to make Scala type inference powerful enough to discover generic type parameter? 的一种尝试规避,可能无法修复。在我的情况下,我不介意获取类型 R 或 Option[R] 的 TypeTag,无论工作如何。

【问题讨论】:

标签: scala type-erasure scala-compiler


【解决方案1】:

这不是改进,恰恰相反,Scala 类型推断根本不支持首先推断 Opt 并从那里得到 R:相反,它推断 Nothing 因为 R 不是任何参数类型的一部分(并且返回类型未知)。

您可以通过在每次调用时显式指定类型参数来规避它:fromOptionFn2[String, Option[String]](...)。在这种特定情况下,给出预期的类型也应该起作用,我认为:fromOptionFn2(...): Wrapper[String]。但是,最好不要一开始就使用 [R, Opt &lt;: Option[R]] 这样的类型参数签名。

【讨论】:

  • 对不起,我忘记了问题中的类型注解(请看我更新的代码sn-p):fromOptionFn的返回类型是Wrapper[R],编译时无法从Opt中推断出来
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多