繁体   English   中英

对于泛型类型和它的类型参数的Scala类型推断 - 为什么它不起作用?

[英]Scala type inference for both a generic type and it's type parameter - why doesn't it work?

如果我要说出关于scala的最令人烦恼的事情,那么对于以下代码:

trait G[+T]
class H[+T] extends G[T]

def f[A<:G[X], X<:Int](g :A)

val g :H[Int]
f(g)

编译器推断最后一次调用f [H [Int],Nothing]的类型,并在我面前因为自己的愚蠢而抱怨。

然而,知道scala,它实际上比我更清楚。 它背后的原因是什么? 由于G和H对于T都是协变的,对于任何类型S, S <: G[X] with H[_] <=> S<: H[X] 。这一个缺点使我设计了一切,避免必须指定明确的类型 - 它可能在这里看起来没什么,但是当名称变成'真实'长度并且几乎任何方法都是通用的,并且经常处理两种泛型类型时,事实证明大多数代码都是类型声明。

编辑:上面的案例在下面由Noah解决,但是当派生类与基类不同时,如下所示?

trait G[+X]
class H[+X, Y] extends G[X]
class F extends G[Int]
def f[A<:G[X], X<:Int](g :A) = g

val h: H[Int, String] = ???
val g :F = ???
f(g)
f(h)

如果你让A坐式paramater A[_]我认为你可以得到Scala编译器同意你的观点,而不是仅仅让一切Nothing

def f[A[_] <: G[_], X <: Int](g: A[X]) 

作为旁注,我通常会在我遇到类型问题时查看scalaz源代码,因为他们通常会遇到它并尽可能地解决它。

UPDATE

我上面提供的方法仍然适用于给出的附加约束:

  trait G[+X]

  class H[+X, Y] extends G[X]

  class F extends G[Int]

  class I extends G[String]

  def f[A[_] <: G[_], X <: Int](g: A[X]) = g

  val h: H[Int, String] = new H[Int, String]
  val g: F = new F
  val i:I = new I
  f(g) //works
  f(h) //works
  f(i) // should fail and does fail

暂无
暂无

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

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