6

我无法在 Scala 中编写以下 F 有界多态性。为什么?

trait X[T <: X[T]]
object Y extends X[Y]

我如何表达这一点并使其编译?

4

2 回答 2

7

看来你真的应该会写,

trait X[T <: X[T]]
object Y extends X[Y.type]

但是,如果您尝试编译器会给您一个无用的(我认为是虚假的)错误,

scala> object Y extends X[Y.type]
<console>:16: error: illegal cyclic reference involving object Y
       object Y extends X[Y.type]

我说“虚假”是因为我们可以用一点额外的基础设施来构造一个等效的对象,

trait X[T <: X[T]]

trait Fix { type Ytype >: Y.type <: Y.type; object Y extends X[Ytype] }
object Fix extends Fix { type Ytype = Y.type }
import Fix.Y

如果您想在实际代码中对此进行试验,使用包对象代替object Fix会使这个习语更有用。

于 2015-08-25T13:43:57.953 回答
1

将其更改为:

  trait Y extends X[Y]

object不是 Scala 中的类型,而是所谓的伴生对象。通过定义object Y,您不能表示它应该扩展trait T[Y],因为第二个Y是指Y尚未定义的类型。但是,您可以执行以下操作:

trait Y extends X[Y]          //If you try this on the REPL, do :paste before
object Y extends X[Y]

在这种情况下,对象在第二个 Y 是您刚刚定义的特征的地方Y扩展X[Y],请确保记住这一点。

于 2015-08-25T12:31:34.397 回答