Search code examples
scalatype-members

Instantiating Scala Type Members results in error


Quick question on why we can't instantiate type members? For example take this example:

abstract class SimpleApplicationLoader {
  type MyComponents <: BuiltInComponentsFromContext

  def load(context: Context) = {
    new MyComponents(context).application
  }
}

class SiteServiceApplicationLoader extends SimpleApplicationLoader {
  type MyComponents = SiteApplicationComponents
}

class SiteApplicationComponents(val context: Context) extends BuiltInComponentsFromContext(context) {
      ....
}

The SimpleApplicationLoader defines a type parameter MyComponents (upper bound to BuiltinComponentsFromContext). In the load method, the type parameter MyComponents is instantiated. SiteServiceApplicationLoader overrides the MyComponents type to _SiteApplicationComponents).

Anyway, the compiler gives the following error:

Error:(13, 9) class type required but SimpleApplicationLoader.this.MyComponents found
    new MyComponents(context).application

Just curious why type members cannot be instantiated? Any workarounds?

Thanks!


Solution

  • Operator new is only available for classes (or "like classes"). Type is not a class, so new is not available.

    To instantiate an arbitrary type, a function could be used

    def newMyComponents(context: Context): MyComponents
    

    Update (thanks to @daniel-werner)

    So the abstract class will look like

    abstract class SimpleApplicationLoader {
      type MyComponents <: BuiltInComponentsFromContext
    
      def newMyComponents(context: Context): MyComponents
    
      def load(context: Context) = {
        newMyComponents(context).application    
      }
    }
    

    The abstract method might be implemented in the class where type is defined:

    class SiteServiceApplicationLoader extends SimpleApplicationLoader {
      type MyComponents = SiteApplicationComponents
      def newMyComponents(context: Context): MyComponents = 
        new SiteApplicationComponents(context)
    }