Search code examples
scalaabstract-type

Use of abstract type in a concrete class?


scala> class A { type T <: String; def f(a: T) = println("foo")}
defined class A

scala> (new A).f("bar")
<console>:9: error: type mismatch;
found   : java.lang.String("bar")
required: _1.T where val _1: A
             (new A).f("bar")
                       ^

Class A has an abstract type T, but is not an abstract class. Creating an object of A (as shown) does not define type T.

My first thought was, I am allowed to pass any type as T which is a subclass of String, but I am not. So what type actually is T in the object and what am I allowed to pass through ?


Solution

  • As you say, T in A is abstract; therefore you won't find any value you can put into method f, until you have a subtype of A which actually fixes T.

    (new A { type T = String }).f("bar")
    

    The idea is that the type can be successively refined:

    trait Var[A] { def get: A; def set(v: A): Unit }
    
    trait Sys {
      type V[A] <: Var[A]
    
      def swap[A](x: V[A], y: V[A]): Unit = {
        val tmp = x.get
        x.set(y.get)
        y.set(tmp)
      }
    }
    
    trait HistVar[A] extends Var[A] { def created: java.util.Date }
    
    trait HistSys extends Sys {
      type V[A] <: HistVar[A]
    
      def newest[A](x: V[A], y: V[A]): A =
        if (x.created after y.created) x.get else y.get
    }
    

    But of course you're question is good -- there is no reason why you would want a concrete instantiation of a class whose type parameter is not fixed. I can't think of a case where that makes sense. (Well of course, you could still have functionality that is accessible, if it does not involve type T)


    Further searching finds the following, quasi duplicate, SO question. You can find there a reference to a Scala ticket which outlines it as a 'feature' -- still doesn't show a case where this 'feature' is actually useful :)