Reputation: 28121
Since I can do this:
case class A(a: Int)
trait C
val x = new A(10) with C
Why can't I do this:
type X = A with C
val x = new X(10)
? If I can't even construct an instance, what's the use case of type X = A with C
?
Upvotes: 1
Views: 353
Reputation: 9705
The error message that you get should give you a hint:
error: class type required but A with C found
new X(10)
^
X
, as a type alias, gets rewritten to an A with C
type expression, which is not a class type. The latter, according to the Scala Language Specification, is:
a type designator (§ 3.2.3 ) that refers to a a class or a trait
(emphasis mine)
In other words, it's not every type expression.
This is not an authoritative answer, but I don't believe it's possible to define a type alias in such a way that it becomes a class type. On the one hand, a new
expression theoretically accepts an AnnotType
, as defined in Section 5.1.1. However, I don't see how, using the type alias grammar from Section 4.3, you could specify what constructor are you using etc..
tl;dr - unless your type alias is directly rewritable to a class type (e.g. A
in your example), you can't use it as a class type, which includes invoking new
with it. If you want that, you need a class declaration, i.e. class X(a: Int) extends A(a) with C
.
Regarding your second question, you say you can't instantiate X
. Ah, but that's where you're wrong! Let me show you an example, based on your code:
def blah(x: X) = x.toString
val x = new A(10) with C
val y = new A(10)
blah(x) //String = A(10)
blah(y) //type error
So, it's useful whenever you need a type constraint, since the "aliased" type will be matched to the type alias, even if it wasn't explicitly declared as such.
Upvotes: 1