I have a question regarding Kotlin and generics. I have a compile error, that I don't understand. I have a very simplified example below. Since Kotlin data classes can't inherit from other data classes, I've done a lot of my class design with composition. That leads to nested data classes. At some points I use generics to switch the type for parameters I can pass into an object. I need to modify values of these data classes and because they are immutable, I use the copy function and put that stuff into a Mutator class.
class Mutator<out P : Params>(val form: Form<P>) { fun modifyName(name: String): Form<P> = when (form.params) { is DefaultParams -> form.copy(params = form.params.copy(name = name)) // compile error is ExtendedParams -> form.copy(params = form.params.copy(name = name)) // compile error else -> form // also.. why do I need that.. Params is sealed.. } } sealed interface Params data class DefaultParams(val name: String) : Params data class ExtendedParams(val name: String, val age: Int) : Params data class Form<out P : Params>(val params: P) fun main() { val form: Form<DefaultParams> = Form(DefaultParams("John")) val mutator: Mutator<DefaultParams> = Mutator(form) val newForm: Form<DefaultParams> = mutator.modifyName("Joe") val next_form: Form<ExtendedParams> = Form(ExtendedParams("John", 30)) val next_mutator: Mutator<ExtendedParams> = Mutator(next_form) val next_newForm: Form<ExtendedParams> = next_mutator.modifyName("Joe") } I get errors on the first two branches of the when block.
Type mismatch. Required: P Found: DefaultParams
Type mismatch. Required: P Found: ExtendedParams
Shouldn't Params be the upper bound of P and thus fine to find DefaultParams or ExtendedParams? And also Params should be sealed, but I need an else block in the when.