Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create an instance of a trait in a generic method in scala?

I'm trying to create an instance of a trait using this method

val inst = new Object with MyTrait

This works well, but I'd like to move this creation in to a generator function, ie.

object Creator {
  def create[T] : T = new Object with T
}

I'm obviously going to need the manifest to somehow fix the type erasure problems, but before I get to this, I run in to 2 questions :

  1. Even with an implicit manifest, Scala still demands that T be a trait. How do I add a restriction to create[T] so that T is a trait?

  2. If I chose to use the Class.newInstance method to create the instance dynamically rather than using "new", how would I specify the "with" in "new Object with T"? Is it possible to dynamically create new concrete mixin types at runtime?

like image 288
ACyclic Avatar asked Jul 18 '10 04:07

ACyclic


1 Answers

I'm not sure what the motivation is for your question, but you could consider passing a factory for T as an implicit parameter. This is known as using type classes or ad-hoc polymorphism.

object Test extends Application {
  trait Factory[T] {
    def apply: T
  }
  object Factory {
    /**
     * Construct a factory for type `T` that creates a new instance by
     * invoking the by-name parameter `t`
     */
    def apply[T](t: => T): Factory[T] = new Factory[T] {
      def apply = t
    }
  }

  // define a few traits...
  trait T1
  trait T2

  // ...and corresponding instances of the `Factory` type class.
  implicit val T1Factory: Factory[T1] = Factory(new T1{})
  implicit val T2Factory: Factory[T2] = Factory(new T2{})

  // Use a context bound to restrict type parameter T
  // by requiring an implicit parameter of type `Factory[T]`
  def create[T: Factory]: T = implicitly[Factory[T]].apply

  create[T1]
  create[T2]

}

At the other end of the spectrum, you could invoke the compiler at runtime, as detailed in this answer to the question "Dynamic mixin in Scala - is it possible?".

like image 119
retronym Avatar answered Oct 14 '22 23:10

retronym