Following is my ADT. Main thing to notice is that Blocks can be nested (look at the children property.
trait Cda {
def format: String = this match {
case f: Field => f.value
case Block(fields, children) => fields.map(f => f.format).mkString("|") + "|" + children.map(b => b.format).mkString("|")
case Record(keys, blocks) => blocks.map(b => b.format).mkString("|")
}
}
trait Field extends Cda {
val name: String
val value: String
}
case class StringField(name: String, value: String) extends Field
case class DateField(name: String, value: String) extends Field
case class TimeField(name: String, value: String) extends Field
case class MatchKey(keyFields: Seq[Field]) extends Cda
case class Block(fields: Seq[Field], children: Seq[Block] = Seq()) extends Cda
case class Record(key: MatchKey, blocks: Seq[Block]) extends Cda
Following is an example instantiation of that ADT
//Block - AI
val aiBlockId = StringField("blockId", "AI")
val addlFieldPos = StringField("AdditionalFieldPosition", "addlFieldPos")
val addlFieldName = StringField("AdditionalFieldName", "addlFieldName")
val AI = Block(Seq(aiBlockId, addlFieldPos, addlFieldName))
//Block - RPS
val rpsBlockId = StringField("blockId", "RPS")
val dateOfStatus = DateField("DateOfStatus", "19240811")
val timeOfStatus = TimeField("TimeOfStatus", "023829")
val rpsBlocks = Seq(rpsBlockId, dateOfStatus, timeOfStatus)
val rpsNestedBlocks = Seq(AI)
val RPS = Block(rpsBlocks, rpsNestedBlocks)
I am expecting to format to return RPS|19240811|023829|AI|addlFieldPos|addlFieldName but I am getting an additional pipe | at the end: RPS|19240811|023829|AI|addlFieldPos|addlFieldName|.
How to change the recursive function format (specifically case Block(fields,children)) to correct this?
Combine the seqs first. It's cheaper to use an iterator, which won't create an intermediate collection.
scala> val as = Seq(1,2,3) ; val bs = Seq.empty[Int]
as: Seq[Int] = List(1, 2, 3)
bs: Seq[Int] = List()
scala> (as ++ bs).mkString("|")
res0: String = 1|2|3
scala> (as.iterator ++ bs).mkString("|")
res1: String = 1|2|3
That is,
case Block(fields, children) => (fields.iterator ++ children).map(_.format).mkString("|")
trait Cda {
def format: String = this match {
case f: Field => f.value
case Block(fields, children) => fields.map(f => f.format).mkString("|") + {if (!children.isEmpty) {"|" + children.map(b => b.format).mkString("|")} else ""}
case Record(keys, blocks) => blocks.map(b => b.format).mkString("|")
}
}
Related
I am trying to convert an RDD of objects to DataFrame, with the peculiarity that said objects have lazy values.
To do this without having to specify the schema of each object by hand, I have created a trait that converts that object to JSON format (or any other text format). The code is the following:
trait Formattable {
lazy val fieldsMap: Map[String, Any] = {
val mirror: Mirror = runtimeMirror(this.getClass.getClassLoader)
val classSymbol: ClassSymbol = mirror.classSymbol(this.getClass)
val instanceMirror: InstanceMirror = mirror.reflect(this)
val laziesNames = classSymbol.info.decls.filter(_.toString.matches("(^|.* )lazy.*$")).map(_.name.toString.trim)
val nonMethodsNames = classSymbol.info.decls.filter(!_.isMethod).map(_.name.toString.trim)
val nonLaziesNames = nonMethodsNames.toSet -- laziesNames.toSet
(laziesNames
.map(name => name -> instanceMirror.reflectMethod(classSymbol.toType.member(TermName(name)).asMethod)()) ++
nonLaziesNames
.map(name => name -> instanceMirror.reflectField(classSymbol.toType.member(TermName(name)).asTerm).get)).toMap
}
def toJSON: String = {
val fieldsStr =
fieldsMap.map(e => s""""${e._1.trim}": ${format(e._2)}""").mkString(",")
s"""{$fieldsStr}"""
}
def format(raw: Any, listSeparator: String = ","): String =
raw match {
case null => """"""""
case _: String => s""""${raw.toString}""""
case _: Char => s""""${raw.toString}""""
case _: Boolean => raw.toString
case _: Int => raw.toString
case _: Float => raw.toString
case _: Double => raw.toString
case _: List[Any] =>
s""""${
raw.asInstanceOf[List[Any]]
.map(format(_, listSeparator)).mkString(listSeparator).replace('"', ''')
}""""
case _: Map[Any, Any] =>
s""""${
raw.asInstanceOf[Map[Any, Any]].values
.map(format(_, listSeparator)).mkString(listSeparator).replace('"', ''')
}""""
case opt: Option[Any] =>
s""""${
opt match {
case Some(value) => value.toString
case None => ""
}
}""""
case obj: Product =>
val objClassMirror: Mirror = runtimeMirror(obj.getClass.getClassLoader)
val objClassSymbol: ClassSymbol = objClassMirror.classSymbol(obj.getClass)
val objInstanceMirror: InstanceMirror = objClassMirror.reflect(obj)
s""""${
objClassSymbol.info.decls
.filter(!_.isMethod) // Filter only attributes
.map(sym => format(objInstanceMirror.reflectField(sym.asTerm).get, listSeparator))
.mkString(listSeparator)
}""""
case date: Date => s""""${new SimpleDateFormat("yyyy-MM-dd").format(date)}""""
case _ => s""""${raw.toString}""""
}
}
Then I have my classes extend this trait, and I convert them to JSON by calling the method toJSON(), and then read them with the method provided by SparkSession:
case class Test (
field1: String,
field2: Double,
...
fieldN: Double
) extends Formattable {
lazy val lazyField1: Double = field2 * fieldN
lazy val lazyField2: Double = fieldN / field2
lazy val lazyField3: Double = lazyField1 * lazyField2
...
}
The code is somewhat more complex, so I was forced to use lazy values.
The problem comes when I try to convert an RDD of objects of this type to DataFrame, since the action is done in a single node, thus losing the power of parallelization of Spark:
val spark: SparkSession = ...
val myRDD: RDD[Test] = ...
import spark.implicits._
val df: DataFrame = spark.read.json(myRDD.map(_.toJSON).toDS())
To put you in context, I am using the following versions:
Spark 2.3.0,
Scala 2.11.0,
Master: yarn-client
Do you have any idea why it can be? Thank you very much in advance.
I want to flatten a nested list structure
MyGrp(List(MyGrp(List(TypeA(2))), MyGrp(List(TypeB(ABC), TypeC(20.0)))))
to List(Type(A),TypeB(ABC),TypeC(20.0))
trait Msg {
def toCustString(flag:Boolean): String
}
trait Ele[T] extends Msg {
val value: T
override def toCustString(flag:Boolean): String = s"${value}"
}
trait Grp extends Msg {
val list: Seq[Msg]
override def toCustString(flag: Boolean = false): String = {
val sep = if (flag) "\n" else "!"
test((builder: StringBuilder, elem: Msg) => builder.append(s"$sep${elem.toCustString(false)}$sep"))
}
def test(acc: (StringBuilder, Msg) => StringBuilder): String = {
list.foldLeft(StringBuilder.newBuilder)(acc).toString()
}
}
case class MyMessage(list:Seq[Msg]) extends Grp
case class TypeA(value: Int) extends Ele[Int]
case class TypeB(value: String) extends Ele[String]
case class TypeC(value: Float) extends Ele[Float]
case class MyGrp (list:Seq[Msg]) extends Grp
object Demo extends App{
val grp1 = MyGrp(Seq(TypeA(2)))
val grp2 = MyGrp(Seq(TypeB("ABC"), TypeC(20)))
val s=MyGrp(Seq(grp1,grp2))
}
I have tried using
s.list.flatten but It says 'Error:(51, 10) No implicit view
available from Msg => scala.collection.GenTraversableOnce[B].
s.list.flatten'
s.list.map(x=>x.toCustString()) but this gives a string form and I want to make a list
You can flatMap with a pattern match, wrapping non-Grps into a single-element list:
val g = MyGrp(List(MyGrp(List(TypeA(2))), MyGrp(List(TypeB("ABC"), TypeC(20.0f)))))
val out = g.list.flatMap {
case grp: Grp => grp.list
case msg => List(msg)
}
How to get all fields with particular type from some object instance including all its parent-classes?
For example, there are these classes:
trait Target {
val message: String
def action: Unit = println("hello", message)
}
class ConcreteTarget(val message: String) extends Target
trait BaseSet {
val s = ""
val t1 = new ConcreteTarget("A")
val t2 = new ConcreteTarget("B")
val a = 123
}
class ExtendedSet extends BaseSet {
val t3 = new ConcreteTarget("C")
val f = "111"
}
I've tried write method for getting all Target fields:
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{universe => ru}
def find(instance: Any): List[Target] = {
val m = ru.runtimeMirror(instance.getClass.getClassLoader)
val i = m.reflect(instance)
i.symbol.typeSignature.decls.flatMap {
case f: TermSymbol if !f.isMethod => i.reflectField(f).get match {
case d: Target => Some(d)
case _ => None
}
case _ => None
}.toList
}
This method works fine for BaseSet:
find(new BaseSet{}) foreach (_.action)
//> (hello,A)
//> (hello,B)
But finds only public fields from ExtendedSet and don't find parents fields:
find(new ExtendedSet) foreach (_.action)
//> (hello,C)
What is wrong?
decls doesn't include inherited members; you are looking for members.
Edit: I've fixed the problem - I was incorrectly calling .map(f => f.typeSignature.asInstanceOf[TypeRef].args.head) on recursiveOpt, which meant that field.name was giving me the wrong field name in my copy method. I've removed the map and everything is working now.
I am writing a macro that will create a map of update methods for a case class, e.g.
case class Inner(innerStr: String)
case class Outer(outerStr: String, inner: Inner, innerOpt: Option[Inner])
should produce an update map for Outer that is something like
val innerMap = Map("innerStr" -> {(json: JsValue) => Try{(inner: Inner) => inner.copy(innerStr = json)}})
val outerMap = Map("outerStr" -> {(json: JsValue) => Try{(outer: Outer) => outer.copy(outerStr = json)}},
"inner.innerStr" -> {(json: JsValue) => Try{(outer: Outer) => innerMap.get("innerStr").get(json).flatMap(update => outer.copy(inner = update(outer.inner)))},
"innerOpt.innerStr" -> {(json: JsValue) => Try{(outer: Outer) => innerMap.get("innerStr").get(json).flatMap(update => outer.copy(inner = outer.inner.map(inner => update(inner))))})
which would then be called like
val oldOuter = Outer("str", Inner("str"), Some(Inner("str")))
val updatedOuter = outerMap.get("inner.innerStr").get(JsString("newStr")).get(oldOuter)
The idea is that given a json kv pair, I can retrieve the appropriate update method from the map using the key and then apply the update using the value, using implicit conversions to convert from the json value to the appropriate type.
My macro is working for the case of a flat case class, e.g. Inner(innerStr: String), and for a nested case class, e.g. Outer(outerStr: String, inner: Inner). However, the case of the nested option case class, Outer(outerStr: String, innerOpt: Option[Inner]), is crashing the compiler. I'm not sure if I'm doing something disastrously wrong, or if there's a bug in the compiler, or third option. This was done using the Scala 2.11.0-M7 REPL
Below is my code - I'm constructing a Map that accepts String input instead of JsValue input so that I don't need to import the play framework into my REPL. The blacklist filters out fields that should not be in the update map (e.g. one of the case classes we're applying this to has fields like "crypted_password" and "salt" that should never be updated via json sent in through a REST route). baseMethods constructs the key -> method tuples for the flat case, recursiveMethods constructs the key-method tuples for the nested case, and recursiveOptMethods constructs the key-value tuples for the nested option case; at the bottom of the macro these are all merged into a flat sequence and a placed in a Map.
I've tested the code in the recursiveOptMethods quasiquotes to ensure that I'm constructing a properly typed sequence of tuples and haven't found an error (also, this code is extremely similar to the recursiveMethods quasiquotes, which are functioning correctly), and I've tested the code that constructs the base, recursive, and recursiveOpt sequences of symbols and they seem to be doing their job.
Any help as to why I'm crashing the compiler would be greatly appreciated.
import scala.language.experimental.macros
def copyTestImpl[T: c.WeakTypeTag](c: scala.reflect.macros.Context)(blacklist: c.Expr[String]*): c.Expr[Map[String, (String) => scala.util.Try[(T) => T]]] = {
import c.universe._
val blacklistList: Seq[String] = blacklist.map(e => c.eval(c.Expr[String](c.resetAllAttrs(e.tree))))
def isCaseClass(tpe: Type): Boolean = tpe.typeSymbol.isClass && tpe.typeSymbol.asClass.isCaseClass
def isCaseClassOpt(tpe: Type): Boolean = tpe.typeSymbol.name.decoded == "Option" && isCaseClass(tpe.asInstanceOf[TypeRef].args.head)
def rec(tpe: Type): c.Expr[Map[String, (String) => scala.util.Try[(T) => T]]] = {
val typeName = tpe.typeSymbol.name.decoded
val fields = tpe.declarations.collectFirst {
case m: MethodSymbol if m.isPrimaryConstructor => m
}.get.paramss.head.filterNot(field => blacklistList.contains(typeName + "." + field.name.decoded))
val recursive = fields.filter(f => isCaseClass(f.typeSignature))
val recursiveOpt = fields.filter(f => isCaseClassOpt(f.typeSignature))
val base = fields.filterNot(f => isCaseClass(f.typeSignature) || isCaseClassOpt(f.typeSignature))
val recursiveMethods = recursive.map {
field => {
val fieldName = field.name
val fieldNameDecoded = fieldName.decoded
val map = rec(field.typeSignature)
q"""{
val innerMap = $map
innerMap.toSeq.map(tuple => ($fieldNameDecoded + "." + tuple._1) -> {
(str: String) => {
val innerUpdate = tuple._2(str)
innerUpdate.map(innerUpdate => (outer: $tpe) => outer.copy($fieldName = innerUpdate(outer.$fieldName)))
}
})}"""
}}
val recursiveOptMethods = recursiveOpt.map {
field => {
val fieldName = field.name
val fieldNameDecoded = fieldName.decoded
val map = rec(field.typeSignature.asInstanceOf[TypeRef].args.head)
q"""{
val innerMap = $map
innerMap.toSeq.map(tuple => ($fieldNameDecoded + "." + tuple._1) -> {
(str: String) => {
val innerUpdate = tuple._2(str)
innerUpdate.map(innerUpdate => (outer: $tpe) => outer.copy($fieldName = (outer.$fieldName).map(inner => innerUpdate(inner))))
}
})}"""
}}
val baseMethods = base.map {
field => {
val fieldName = field.name
val fieldNameDecoded = fieldName.decoded
val fieldType = field.typeSignature
val fieldTypeName = fieldType.toString
q"""{
$fieldNameDecoded -> {
(str: String) => scala.util.Try {
val x: $fieldType = str
(t: $tpe) => t.copy($fieldName = x)
}.recoverWith {
case e: Exception => scala.util.Failure(new IllegalArgumentException("Failed to parse " + str + " as " + $typeName + "." + $fieldNameDecoded + ": " + $fieldTypeName))
}
}}"""
}}
c.Expr[Map[String, (String) => scala.util.Try[(T) => T]]] {
q"""{ Map((List(..$recursiveMethods).flatten ++ List(..$recursiveOptMethods).flatten ++ List(..$baseMethods)):_*) }"""
}
}
rec(weakTypeOf[T])
}
def copyTest[T](blacklist: String*) = macro copyTestImpl[T]
And the top and bottom of my error from the 2.11.0-M7 REPL when calling copyTest[Outer]() (where Outer has an Option[Inner] field)
scala> copyTest[Outer]()
scala.MatchError: AnyRef
with Product
with Serializable {
val innerStr: String
private[this] val innerStr: String
def <init>(innerStr: String): Inner
def copy(innerStr: String): Inner
def copy$default$1: String #scala.annotation.unchecked.uncheckedVariance
override def productPrefix: String
def productArity: Int
def productElement(x$1: Int): Any
override def productIterator: Iterator[Any]
def canEqual(x$1: Any): Boolean
override def hashCode(): Int
override def toString(): String
override def equals(x$1: Any): Boolean
} (of class scala.reflect.internal.Types$ClassInfoType)
at scala.reflect.internal.Variances$class.inType$1(Variances.scala:181)
at scala.reflect.internal.Variances$$anonfun$inArgs$1$1.apply(Variances.scala:176)
at scala.reflect.internal.Variances$$anonfun$inArgs$1$1.apply(Variances.scala:176)
at scala.reflect.internal.util.Collections$class.map2(Collections.scala:55)
at scala.reflect.internal.SymbolTable.map2(SymbolTable.scala:14)
at scala.reflect.internal.Variances$class.inArgs$1(Variances.scala:176)
at scala.reflect.internal.Variances$class.inType$1(Variances.scala:189)
at scala.reflect.internal.Variances$$anonfun$inArgs$1$1.apply(Variances.scala:176)
at scala.reflect.internal.Variances$$anonfun$inArgs$1$1.apply(Variances.scala:176)
at scala.reflect.internal.util.Collections$class.map2(Collections.scala:55)
at scala.reflect.internal.SymbolTable.map2(SymbolTable.scala:14)
at scala.tools.nsc.typechecker.Analyzer$typerFactory$$anon$3.run(Analyzer.scala:93)
at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1603)
at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1588)
at scala.tools.nsc.Global$Run.compileSources(Global.scala:1583)
at scala.tools.nsc.interpreter.IMain.compileSourcesKeepingRun(IMain.scala:387)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.compileAndSaveRun(IMain.scala:816)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.compile(IMain.scala:775)
at scala.tools.nsc.interpreter.IMain$Request.compile$lzycompute(IMain.scala:951)
at scala.tools.nsc.interpreter.IMain$Request.compile(IMain.scala:946)
at scala.tools.nsc.interpreter.IMain.compile(IMain.scala:530)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:518)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:516)
at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:748)
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:793)
at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:660)
at scala.tools.nsc.interpreter.ILoop.processLine(ILoop.scala:427)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:444)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:862)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:848)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:848)
at scala.reflect.internal.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:95)
at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:848)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:81)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:94)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
That entry seems to have slain the compiler. Shall I replay
your session? I can re-run each line except the last one.
I found the problem - originally I had val recursiveOpt = fields.filter(f => isCaseClassOpt(f.typeSignature)).map(f => f.typeSignature.asInstanceOf[TypeRef].args.head), which meant that when I called field.name on the recursiveOpt fields I was getting the wrong name back.
I'm building a web-application using Play and Slick, and find myself in a situation where the user-facing forms are similar, but not exactly the same as the database model.
Hence I have two very similar case classes, and need to map from one to another (e.g. while filling the form for rendering an "update" view).
In the case I'm interested in, the database model case class is a super-set of the form case-class, i.e. the only difference between both is that the database model has two more fields (two identifiers, basically).
What I'm now wondering about is whether there'd be a way to build a small library (e.g. macro-driven) to automatically populate the form case class from the database case class based on the member names. I've seen that it may be possible to access this kind of information via reflection using Paranamer, but I'd rather not venture into this.
Here is a solution using Dynamic because I wanted to try it out. A macro would decide statically whether to emit an apply of a source value method, the default value method, or just to supply a literal. The syntax could look something like newFrom[C](k). (Update: see below for the macro.)
import scala.language.dynamics
trait Invocable extends Dynamic {
import scala.reflect.runtime.currentMirror
import scala.reflect.runtime.universe._
def applyDynamic(method: String)(source: Any) = {
require(method endsWith "From")
def caseMethod(s: Symbol) = s.asTerm.isCaseAccessor && s.asTerm.isMethod
val sm = currentMirror reflect source
val ms = sm.symbol.asClass.typeSignature.members filter caseMethod map (_.asMethod)
val values = ms map (m => (m.name, (sm reflectMethod m)()))
val im = currentMirror reflect this
invokeWith(im, method dropRight 4, values.toMap)
}
def invokeWith(im: InstanceMirror, name: String, values: Map[Name, Any]): Any = {
val at = TermName(name)
val ts = im.symbol.typeSignature
val method = (ts member at).asMethod
// supplied value or defarg or default val for type of p
def valueFor(p: Symbol, i: Int): Any = {
if (values contains p.name) values(p.name)
else ts member TermName(s"$name$$default$$${i+1}") match {
case NoSymbol =>
if (p.typeSignature.typeSymbol.asClass.isPrimitive) {
if (p.typeSignature <:< typeOf[Int]) 0
else if (p.typeSignature <:< typeOf[Double]) 0.0
else ???
} else null
case defarg => (im reflectMethod defarg.asMethod)()
}
}
val args = (for (ps <- method.paramss; p <- ps) yield p).zipWithIndex map (p => valueFor(p._1,p._2))
(im reflectMethod method)(args: _*)
}
}
case class C(a: String, b: Int, c: Double = 2.0, d: Double)
case class K(b: Int, e: String, a: String)
object C extends Invocable
object Test extends App {
val res = C applyFrom K(8, "oh", "kay")
Console println res // C(kay,8,2.0,0.0)
}
Update: Here is the macro version, more for fun than for profit:
import scala.language.experimental.macros
import scala.reflect.macros._
import scala.collection.mutable.ListBuffer
def newFrom[A, B](source: A): B = macro newFrom_[A, B]
def newFrom_[A: c.WeakTypeTag, B: c.WeakTypeTag](c: Context)(source: c.Expr[A]): c.Expr[B] = {
import c.{ literal, literalNull }
import c.universe._
import treeBuild._
import nme.{ CONSTRUCTOR => Ctor }
def caseMethod(s: Symbol) = s.asTerm.isCaseAccessor && s.asTerm.isMethod
def defaulter(name: Name, i: Int): String = s"${name.encoded}$$default$$${i+1}"
val noargs = List[c.Tree]()
// side effects: first evaluate the arg
val side = ListBuffer[c.Tree]()
val src = TermName(c freshName "src$")
side += ValDef(Modifiers(), src, TypeTree(source.tree.tpe), source.tree)
// take the arg as instance of a case class and use the case members
val a = implicitly[c.WeakTypeTag[A]].tpe
val srcs = (a.members filter caseMethod map (m => (m.name, m.asMethod))).toMap
// construct the target, using src fields, defaults (from the companion), or zero
val b = implicitly[c.WeakTypeTag[B]].tpe
val bm = b.typeSymbol.asClass.companionSymbol.asModule
val bc = bm.moduleClass.asClass.typeSignature
val ps = (b declaration Ctor).asMethod.paramss.flatten.zipWithIndex
val args: List[c.Tree] = ps map { case (p, i) =>
if (srcs contains p.name)
Select(Ident(src), p.name)
else bc member TermName(defaulter(Ctor, i)) match {
case NoSymbol =>
if (p.typeSignature.typeSymbol.asClass.isPrimitive) {
if (p.typeSignature <:< typeOf[Int]) literal(0).tree
else if (p.typeSignature <:< typeOf[Double]) literal(0.0).tree
else ???
} else literalNull.tree
case defarg => Select(mkAttributedRef(bm), defarg.name)
}
}
c.Expr(Block(side.toList, Apply(Select(New(mkAttributedIdent(b.typeSymbol)), Ctor), args)))
}
With usage:
case class C(a: String, b: Int, c: Double = 2.0, d: Double)
case class K(b: Int, e: String, a: String) { def i() = b }
val res = newFrom[K, C](K(8, "oh", "kay"))