Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the type result in "Product with Serializable with Animal" instead of just Animal?

Tags:

types

scala

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? 
like image 286
Srinivas Avatar asked Jan 27 '23 05:01

Srinivas


1 Answers

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.

like image 90
Mario Galic Avatar answered May 08 '23 11:05

Mario Galic