I am actually not clear whether the following were a view or context bound. Also not clear what the self referential aspect (re-referencing Model) is doing ;) :
abstract class Model[M <: Model[M]] extends Transformer {
An explanation on the meaning of "<: Model[M]" would be appreciated.
<:
is neither a view nor context bound, but a type bound.
Below is an extended example of how self referential type bounds can be used.
The class ModelA
uses a more restrictive type bound M <: ModelA[M]
in order to make the method fooN
work. ModelA2
can still extend ModelA[ModelA1]
, but not ModelA[ModelB1]
. On the other hand, the class ModelB
doesn't further restrict the type bound, so ModelB2
can extend ModelB[ModelA1]
. The methods bar1
and bar2
restrict either the type bound or the parameter model
, depending on the order in which the methods transform
and bar
are called on model
.
object Main extends App {
val a: ModelA1 = foo(new ModelA1(), 2)
val b: ModelA1 = foo(new ModelA2(), 3)
val c: ModelB1 = bar1(new ModelB1())
val d: ModelA1 = bar2(new ModelB2())
def foo[M <: ModelA[M]](model: Model[M], n: Int): M = model.transform.fooN(n)
def bar1[M <: ModelB[M]](model: Model[M]): M = model.transform.bar
def bar2[M <: Model[M]](model: ModelB[M]): M = model.bar.transform
}
abstract class Model[M <: Model[M]] {
def transform: M
}
abstract class ModelA[M <: ModelA[M]] extends Model[M] {
def foo: M
def fooN(n: Int): M = {
var x: M = this.foo
for (_ <- 2 to n)
x = x.foo
x
}
}
abstract class ModelB[M <: Model[M]] extends Model[M] {
def bar: M
}
class ModelA1 extends ModelA[ModelA1] {
override def transform: ModelA1 = ???
override def foo: ModelA1 = ???
}
class ModelA2 extends ModelA[ModelA1] {
override def transform: ModelA1 = ???
override def foo: ModelA1 = ???
}
class ModelB1 extends ModelB[ModelB1] {
override def transform: ModelB1 = ???
override def bar: ModelB1 = ???
}
class ModelB2 extends ModelB[ModelA1] {
override def transform: ModelA1 = ???
override def bar: ModelA1 = ???
}