title: Instantiating a case class from a list of parameters
body: <p>Given:</p>
  
  <pre><code>case class Foo(a: Int, b: String, c: Double)
  </code></pre>
  
  <p>you can say:</p>
  
  <pre><code>val params = Foo(1, "bar", 3.14).productIterator.toList
  </code></pre>
  
  <p>and get:</p>
  
  <pre><code>params: List[Any] = List(1, bar, 3.14)
  </code></pre>
  
  <p>Is there a way to "go backwards" and recreate a Foo object directly from this list, i.e.:</p>
  
  <pre><code>Foo.createFromList(params)   // hypothetical
  </code></pre>
  
  <p>instead of writing:</p>
  
  <pre><code>Foo(params(0).asInstanceOf[Int], params(1).asInstanceOf[String], params(2).asInstanceOf[Double])
  </code></pre>
  
  <p>EDIT: it seems that it boils down to being able to send the elements of a list as parameters to a function without writing them out explicitly, e.g.:</p>
  
  <pre><code>def bar(a: Int, b: Int, c: Int) = //...
  val list = List(1, 2, 3, 4, 5)
  bar(list.take(3)) // hypothetical, instead of:
  bar(list(0), list(1), list(2))
  </code></pre>
  
  <p>I would sort of expect to be able to do:</p>
  
  <pre><code>bar(list.take(3): _*)
  </code></pre>
  
  <p>but that doesn't seem to work.</p>
  
  <p>EDIT: Solution based on extempore's answer, but invoking the constructor directly instead of using the apply method:</p>
  
  <pre><code>case class Foo(a: Int = 0, b: String = "bar", c: Double = 3.14) {
      val cs = this.getClass.getConstructors
      def createFromList(params: List[Any]) =
      cs(0).newInstance(params map { _.asInstanceOf[AnyRef] } : _*).asInstanceOf[Foo]
  }
  </code></pre>
  
  <p>Now you can do:</p>
  
  <pre><code>scala&gt; Foo().createFromList(List(4, "foo", 9.81))
  res13: Foo = Foo(4,foo,9.81)
  </code></pre>
  
  <p>You can also refactor the creation method into a trait:</p>
  
  <pre><code>trait Creatable[T &lt;: Creatable[T]] {
      val cs = this.getClass.getConstructors
      def createFromList(params: List[Any]) =
          cs(0).newInstance(params map { _.asInstanceOf[AnyRef] } : _*).asInstanceOf[T]   
  }
  
  case class Bar(a: Int = 0, b: String = "bar", c: Double = 3.14) extends Creatable[Bar]
  </code></pre>
  
  <p>And do e.g.:</p>
  
  <pre><code>scala&gt; val bar = Bar()
  bar: Bar = Bar(0,bar,3.14)
  
  scala&gt; bar == bar.createFromList(bar.productIterator.toList)
  res11: Boolean = true
  </code></pre>