I cannot write the following F-bounded polymorphism in Scala. Why?
trait X[T <: X[T]]
object Y extends X[Y]
How can I express this and make it compile?
It really seems like you ought to be able to write,
trait X[T <: X[T]]
object Y extends X[Y.type]
however, if you try that the compiler will give you an unhelpful (and I think spurious) error,
scala> object Y extends X[Y.type]
<console>:16: error: illegal cyclic reference involving object Y
object Y extends X[Y.type]
I say "spurious" because we can construct an equivalent object with a little bit of additional infrastructure,
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
If you wanted to experiment with this in real code, using a package object in place of object Fix
would make this idiom a little more usable.
Change it to :
trait Y extends X[Y]
object
is not a type in Scala, but the so called companion object.
By defining object Y
, you can't express that it should extend trait T[Y]
, since that second Y
refers to a type Y
that hasn't been defined.
You can however do the following:
trait Y extends X[Y] //If you try this on the REPL, do :paste before
object Y extends X[Y]
In this case the object Y
extends X[Y]
where the second Y is the trait you just define, make sure you keep this in mind.
来源:https://stackoverflow.com/questions/32203867/scala-f-bounded-polymorphism-on-object