存在类型和类型成员的Scala类型推断

aak*_*hns 8 scala type-inference existential-type type-members

以下代码无法编译:

trait A[F] {
  def find(x: Int): F
  def fill(f: F): Unit
}

object TestA {
  def test[T <: A[F] forSome { type F }](t: T) =
    t.fill(t.find(0))
}
Run Code Online (Sandbox Code Playgroud)

它返回以下编译错误:

test.scala:8: error: type mismatch;
 found   : (some other)F(in type T)
 required: F(in type T)
    t.fill(t.find(0))
                 ^
Run Code Online (Sandbox Code Playgroud)

但是,以下代码符合以下条件:

trait B[F] {
  type R = F
  def find(x: Int): R
  def fill(f: R): Unit
}

object TestB {
  def test[T <: B[F] forSome { type F }](t: T) =
    t.fill(t.find(0))
}
Run Code Online (Sandbox Code Playgroud)

我这里有两个问题:

  1. 我希望第一段代码能够编译.为什么不呢?

  2. 如果有一个很好的理由为什么第一段代码不能编译,我会期望第二段也不能编译,出于同样的原因.那怎么编译成功呢?

这些都是错误吗?

小智 3

我不知道编译器为什么要区分这两段代码。基本上,代码不会编译,因为返回的类型find和预期的类型fill不必相同F,至少在两个不同的对象上调用find和时fill是这样。

您可以使用以下代码来编译第一段代码:

def test[T <: A[F], F](t: T) =
  t.fill(t.find(0))
Run Code Online (Sandbox Code Playgroud)

你可以使第二段代码不编译:

def test[T <: B[F] forSome { type F }](t: T, u: T) =
  t.fill(u.find(0))
Run Code Online (Sandbox Code Playgroud)

这应该是一条评论而不是一个答案,但我还没有 50 声望。