Why can I say that a type field has the type of a class with another class mixed into it (when only traits can be mixed in a class) ?
Example:
scala> class A
defined class A
scala> class B extends A
defined class B
Mixing in B
to A
is not allowed:
scala> new A with B
<console>:10: error: class B needs to be a trait to be mixed in
new A with B
^
But this is possible:
scala> class E {type T = A with B}
defined class E
scala> new E
res1: E = E@1f2bc83
There is a difference between the mixin instantiation and the compound type definition.
First of all the type A with B
exists and is exactly the type B
, alas it is perfectly legal in scala to write
val x: A with B = new B
as is
val y: Any with AnyRef with A with B = new B
as it describes exactly the same type. You are just introducing restrictions in the type of the value you can assign to a variable of that type. These restrictions of course always hold in that case.
Furthermore you have to keep in mind that Scala does not necessarily need a type to be inhabited - i.e. the bottom type Nothing
may not be instantiated at all.
But as Nothing
is a subtype of every type that can be expressed in Scala it is even valid to write an expression like
def foo: AnyRef with AnyVal = sys.error("IMPOSSIBRU!")
Nothing
is a subtype of AnyRef with AnyVal
by definition thus that declaration typechecks.
This is called a compound type and has nothing to do with traits. It allows you to express that a type is a subtype of several other types.
For more information where they can occur see the Scala tag info in section "type handling".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With