I have recently learnt about cake pattern and the differences between the uses of self =>
and self:T =>
(see here). The difference between these technicalities and real Scala code as remarked here continue to create me problems. For instance, see the following code snippet taken from the Inox project:
trait Trees
extends Expressions
with Constructors
with Extractors
with Types
with Definitions
with Printers
with TreeOps { self =>
...
val interpolator: Interpolator { val trees: Trees.this.type } = new {
protected val trees: Trees.this.type = Trees.this
} with Interpolator
...
}
In summary, the whole snippet does not make much sense to me (and it is a pattern frequently repeated in the code), let me explain:
val interpolator: Interpolator { ... }
up to now I wrote val name: Type = value
, here there is no equal.
Trees.this.type
should be a type, but what type? It should be defined in Trees trait, and the this
context which I bet is different from the trait Trees
context (related to problem 1). I also looked on file Interpolators but there does not seem to be a type element.
The greatest line is protected val trees: Trees.this.type = Trees.this
.
Can anybody explain me what is going on here?
It's a declaration of variable interpolator
with type Interpolator { val trees: Trees.this.type }
. The type Interpolator { val trees: Trees.this.type }
is a subtype of Interpolator
, but refined with the additional restriction that trees
is not just some Trees
, but instead one concrete instance of Trees
, namely the one of the singleton type Trees.this.type
. There is an equal-=
-symbol: between the type Interpolator { val trees: Trees.this.type }
and the new { ... } with Interpolator
.
Shorter example which demonstrates the syntax in isolation:
trait Foo {
val trees: Any
}
def interpolator: Foo { val trees: Int } =
new Foo { val trees = 42 }
interpolator.trees + 58
Trees.this.type
is the singleton type of the value this
. There is only one value of this type: Trees.this
.
Shorter example that demonstrates usage of .type
:
class Bar
val b = new Bar
val c: b.type = b
You are setting the value trees
to Trees.this
. You also guarantee to the compiler that trees
is not just some Trees
, but that trees
is the singleton value Trees.this
of the singleton type Trees.this.type
, which is a strict subtype of Trees
.