【问题标题】:Scala F-bounded polymorphism on object对象上的 Scala F 有界多态性
【发布时间】:2015-08-25 21:43:57
【问题描述】:

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

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

如何表达并编译?

【问题讨论】:

    标签: scala object f-bounded-polymorphism


    【解决方案1】:

    看来你真的应该会写,

    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 会使这个习惯用法更实用。

    【讨论】:

    • 您认为这是编译器错误还是规范中的疏忽?或者也许有一些我们没有看到的微妙之处使得错误成为必要?
    • 与@retronym 在scala/scala 上的对话表明这是一个错误。还有works as expected on Dotty.
    【解决方案2】:

    改成:

      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 扩展了X[Y],其中第二个 Y 是您刚刚定义的特征,请务必牢记这一点。

    【讨论】:

    • 我希望 Y 只被实例化一次并访问它的唯一实例,这就是我需要一个对象的原因。
    • 然后您可以使用 class Y private() extends X[Y] 将构造函数设为私有,然后将该实例公开。
    猜你喜欢
    • 2016-09-22
    • 1970-01-01
    • 2015-06-21
    • 2015-03-09
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 2017-04-26
    相关资源
    最近更新 更多