I am learning scala and tried following form Scala Cookbook:
trait Animal
trait FurryAnimal extends Animal
case class Dog(name:String) extends Animal
case class Cat(name:String) extends Animal
Now when I did following as :
val x = Array(Dog("Fido"),Cat("Felix"))
it show result as :
x:Array[Product with Serializable with Animal] = Array(Dog(Fido),Cat(Felix))
Although I know that a case class is mixed in with Product trait
What I am not getting is : Product with Serializable with Animal
As per my understanding Product has something to do with Pattern matching
I did google it but didn't get anything.Please Help to get me the concept in detail.
Thanks
This is an expected behavior because of how case class
works. case class
automatically extends
two traits, namely Product
and Serializable
.
Product
trait is extended as case class
is an algebraic data type with product type.
Serializable
trait is extended so that case class
can be treated as a pure data - i.e capable of being serialized.
Unlike case class
Dog
and Cat
, your trait Animal
does not extend Product
or Serializable
. Hence the type signature you see.
When you declare something like Array(Dog(""), Cat(""))
, scalac needs to infer single top type that can represent all the elements of given array.
That's why the inferred type is Product with Serializable with Animal
as Animal
did not extend Product
nor Serializable
while the case class
did implicitly.
To work around this inference, you can either make type explicit by Animal
or make Animal
extend Product
and Serializable
.
trait Animal extends Product with Serializable
case class Dog(name: String) extends Animal
case class Cat(name: String) extends Animal
Array(Dog(""), Cat("")) // Array[Animal] = Array(Dog(), Cat())