Suppose I have
val flag = true
why does the type result in Product with Serializable with Animal instead of just Animal?
class Animal(name : String)
case class Herbivore(name : String) extends Animal(name)
case class Carnivore(name : String) extends Animal(name)
val cow = new Herbivore("cow")
val tiger = new Carnivore("tiger")
if (flag) cow else tiger // Why is type Product with Serializable with Animal? 
Case classes automatically extend Product with Serializable so 
class Animal(name : String)
case class Herbivore(name : String) extends Animal(name)
case class Carnivore(name : String) extends Animal(name)
is actually
class Animal(name : String)
case class Herbivore(name : String) extends Animal(name) with Product with Serializable
case class Carnivore(name : String) extends Animal(name) with Product with Serializable
Hence the most precise type of if (flag) cow else tiger expression compiler can infer is Product with Serializable with Animal. If we change from case classes to just classes like so
class Animal(name : String)
class Herbivore(name : String) extends Animal(name)
class Carnivore(name : String) extends Animal(name)
then the inferred type of the if-else expression would indeed be Animal.
As per @TravisBrown's suggestion, making ADT root extend Product with Serializable like so
abstract class Animal(name : String) extends Product with Serializable
case class Herbivore(name : String) extends Animal(name)
case class Carnivore(name : String) extends Animal(name)
would make the inferred type of the if-else expression also Animal.
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