Scala中的编译问题,具有F-bounded类型和存在类型

Yan*_*san 3 types type-systems scala existential-type f-bounded-polymorphism

我正在使用F-bounded类型以便能够返回当前类型

trait Board[T <: Board[T]] {
  def updated : T
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个使用它的通用辅助方法.

问题是:为什么以下不编译?

object BoardOps {
  def updated(board: Board[_]) = {
    board.updated.updated
  }
}
Run Code Online (Sandbox Code Playgroud)

错误是 value updated is not a member of _$1

我已经找到了这2个解决方法.它们是等价的吗?

object BoardOps {
  def updated(board: Board[_<:Board[_]]) = {
    board.updated.updated
  }
}

object BoardOps {
  def updated[T <: Board[T]](board: T) : T = {
    board.updated.updated
  }
}
Run Code Online (Sandbox Code Playgroud)

Yuv*_*kov 5

为什么以下不编译?

使用Board[_]作为参数类型告诉编译器"我不关心板内参数的类型".也就是说,这对于编译器来说是一种存在类型,它不知道有关该类型的任何细节.因此,board.updated返回"unspeakable"或opaque类型,因为我们告诉编译器"抛弃"该类型信息.

我已经找到了这2个解决方法.它们是等价的吗?

您以前的示例使用具有约束的存在类型作为子类型Board[_],或者更正式地我们编写:

Board[T] forSome { type T <: Board[U] }
Run Code Online (Sandbox Code Playgroud)

编译器的实际名称T -> $_1和位置U -> $_2

同样,我们对内部类型参数一无所知,只是它有一个上限Board[_].后一个示例使用命名的通用量化类型T,编译器可以使用该类型将方法的返回类型推导为特定类型T而不是Any.

要回答你的问题,不,它们不相同.存在的和普遍量化的类型彼此是 双重的.关于存在的更多信息可以在什么是存在类型上找到?https://www.drmaciver.com/2008/03/existential-types-in-scala/