How to manage type variance in Scala case classes for a polymorphic collection?
I'm writing unit tests and I'm working with Scala 2.13 and I have a polymorphic collection of case classes that need to support different types in a homogeneous way. I've defined a base trait and several case classes that extend it. My scenario arises when I try to add instances of these case classes to a collection of the base trait type, as I'm working with a `type mismatch` behavior. Here's a simplified version of my code: ```scala sealed trait Animal { def sound: String } case class Dog(name: String) extends Animal { def sound: String = "Bark" } case class Cat(name: String) extends Animal { def sound: String = "Meow" } val animals: List[Animal] = List(Dog("Rex"), Cat("Whiskers")) ``` This compiles without issues, but when I try to use a method that requires a specific type, like this: ```scala def makeSound(animal: Dog): String = animal.sound val sounds: List[String] = animals.map(makeSound) ``` I get the following behavior: `type mismatch; found : Animal required: Dog`. I understand that the method expects a `Dog`, but I'm trying to call it on a list that contains both `Dog` and `Cat` instances. I've tried using pattern matching in the map function like this: ```scala val sounds: List[String] = animals.map { case dog: Dog => makeSound(dog) case _ => "Unknown" } ``` However, I'm still not satisfied with this approach because it feels hacky and breaks the type safety. I want a more idiomatic way to handle this situation while maintaining type safety and leveraging Scala's functional programming capabilities. Any suggestions on how to achieve this cleanly? This issue appeared after updating to Scala 3.11. Cheers for any assistance! I'm working on a service that needs to handle this. Could this be a known issue?