Lai Yu-Hsuan
Lai Yu-Hsuan

Reputation: 28121

Type alias for mix-in type

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

Answers (1)

mikołak
mikołak

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

Related Questions