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.