I wonder whether using generics for Scala case classes can save some boilerplate code.
Let's save I have the following class hieararchy to emulate a "variant" type that boxes a set of types and allows unboxing them using pattern matching:
sealed abstract class Box;
case class DoubleBox(v: Double) extends Box;
case class StringBox(v: String) extends Box;
case class BooleanBox(v: Boolean) extends Box;
def typeName(b: Box) = b match {
case DoubleBox(v) => "Double"
case StringBox(v) => "String"
case BooleanBox(v) => "Boolean"
case _ => "Unknown"
}
There may be places in the code where it would be more convenient to deal with the leaf case classes if they were generics. Something like:
sealed abstract class Box;
case class TypedBox[T](v: T) extends Box;
def typeName2(b: Box) = b match {
case TypedBox[Double](v) => "Double"
case TypedBox[String](v) => "String"
case TypedBox[Boolean](v) => "Boolean"
case _ => "Unknown"
}
But this doesn't compile. As far as I understand this syntax is not really recognized as valid Scala syntax.
Is it possible to make what I want working or it's a bad idea and I just don't get something?
EDIT: Vinicius answered my question, but looking at the answer I have another question. Is it possible to hint the compiler somehow that only certain list of types can be used to parameters TypedBox? I want that to make sure the compiler can still do exhaustiveness check of TypedBox usage/matching.
To use a generic class, put the type in the square brackets in place of A . Class Apple and Banana both extend Fruit so we can push instances apple and banana onto the stack of Fruit . Note: subtyping of generic types is *invariant*.
Most Scala generic classes are collections, such as the immutable List, Queue, Set, Map, or their mutable equivalents, and Stack. Collections are containers of zero or more objects. We also have generic containers that aren't so obvious at first.
What is Scala Case Class? A Scala Case Class is like a regular class, except it is good for modeling immutable data. It also serves useful in pattern matching, such a class has a default apply() method which handles object construction. A scala case class also has all vals, which means they are immutable.
=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .
Try
sealed abstract class Box;
case class TypedBox[T](v: T) extends Box;
def typeName2(b: Box) = b match {
case TypedBox(v: Double) => "Double"
case TypedBox(v: String) => "String"
case TypedBox(v: Boolean) => "Boolean"
case _ => "Unknown"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With