I want to group elements of different types into one.
Following is one example
trait Element
case class ElementString(key:String,value:String) extends Element
case class ElementDouble(key:String,value:Double) extends Element
case class ElementInt(key:String,value:Int) extends Element
Grp(ElementString("2","abc"),ElementDouble("3",100.20),ElementInt("4",10))
Updated
I would also like to create a Group inside a Group.
A DSL like this is very common in scala because it is type-safe, but also very concise to use:
trait Value
object Value {
case class StringValue(value: String) extends Value
case class DoubleValue(value: Double) extends Value
case class IntValue(value: Int) extends Value
}
case class Element(key: String, value: Value)
object Element {
implicit def fromStringPair (a: (String,String)) = Element(a._1, Value.StringValue(a._2))
implicit def fromDoublePair (a: (String,Double)) = Element(a._1, Value.DoubleValue(a._2))
implicit def fromIntPair (a: (String,Int)) = Element(a._1, Value.IntValue(a._2))
}
case class Grp (elements: Element*)
Grp(
"2" -> "abc",
"3" -> 100.20,
"4" -> 10
)
//: Grp = Grp(WrappedArray(Element(2,StringValue(abc)), Element(3,DoubleValue(100.2)), Element(4,IntValue(10))))
Alternative, no varargs:
trait Value
// define these in different files if you want
case class Student(value: String) extends Value
case class Employee(value: Double) extends Value
case class Department(value: Int) extends Value
case class Element(key: String, value: Value)
case class Grp (elements: List[Element] = Nil) extends Value {
def add (key: String, value: Value): Grp = Grp(this.elements ++ List(Element(key, value)))
}
Grp()
.add("2", Student("abc"))
.add("3", Employee(100.20))
.add("4", Department(10))
.add("5", Grp().add("2", Student("xyz"))) // nested group
You can use a quasi builder pattern by adding the a function:
def withElement(elem: Element) = copy(group = group :+ elem)
Assuming group is a list. Note that this does make a new copy of the case class each time you call withElement
. The code would then look like:
Grp().withElement(...).withElement(...)
You could create a real builder pattern if performance was important.