Concrete classes with abstract type elements

Given the following features and class. Why is this compiling? Can it really be used for something?

trait Container { type A } trait AnotherContainer[B]{ def x(b : B) : B } trait Mixed extends Container with AnotherContainer[Container#A] class Impl extends Mixed{ def x(a : Container#A) = a } new Impl().x _ scala> new Impl().x _ res0: (Container#A) => Container#A = <function> 

Update:

 class Baz { type T; } 

This is actually a feature, but I could not find motivation for it: # 1753 .

+6
types scala
source share
2 answers

It looks harmless if useless to me. The type that x wants does not exist, so you cannot pass it to a method. I believe that harmless futility should be a compile-time error - that is a matter of taste.

If you look at what x actually does, it decompiles:

 public java.lang.Object x(java.lang.Object); Code: 0: aload_1 1: areturn 

which is what the identification method should do (load the argument regardless of type, return it). You can write something equivalent with much less code:

 trait AbstractType { type T } class Useless extends AbstractType { def identity(t: AbstractType#T) = t } 

Except that nothing is of type AbstractType # T, we again have no use.

If I'm missing something.

+2
source share

In your example, the compiler adds default type evaluations >: Nothing <: Any . The second example below shows the case when an abstract type becomes usable (if not useful).

 scala> trait T { type A >: Nothing <: Any } defined trait T scala> 1: T#A <console>:6: error: type mismatch; found : Int(1) required: T#A 1: T#A ^ scala> trait T { type A >: Int <: Int } defined trait T scala> 1: T#A res6: T#A = 1 scala> "": T#A <console>:6: error: type mismatch; found : java.lang.String("") required: T#A "": T#A ^ 
+3
source share

All Articles