Davide Giuseppe Farella
05/20/2024, 3:45 PMelse
branch?
https://pl.kotl.in/NB1wSZ8su
sealed interface Base
data class One(
val name: String,
val count: Int
) : Base
data class Two(
val name: String,
val count: Int
) : Base
fun <T : Base> T.rename(newName: String): T =
when (this) {
is One -> copy(name = newName)
is Two -> copy(name = newName)
// else branch required!
}
ephemient
05/20/2024, 3:50 PMYoussef Shoaib [MOD]
05/20/2024, 3:55 PMelse
branch, you need a cast as T
because copy
methods aren't seen as returning self
automatically.
Btw, this works:
fun <T : Base> T.rename(newName: String): T = with<Base, _>(this){
when (this) {
is One -> copy(name = newName)
is Two -> copy(name = newName)
} as T
}
Youssef Shoaib [MOD]
05/20/2024, 3:56 PMfun <T : Base> T.rename(newName: String): T {
val base: Base = this
return when (base) {
is One -> base.copy(name = newName)
is Two -> base.copy(name = newName)
} as T
}
ephemient
05/20/2024, 3:57 PMfun One.rename(newName: String): One = copy(name = newName)
fun Two.rename(newName: String): Two = copy(name = newName)
fun Base.rename(newName: String): Base = when (this) {
is One -> rename(newName)
is Two -> rename(newName)
}
all the callers with specific types get the right resulting types, and callers with wider types don't care about the specifics anywayDavide Giuseppe Farella
05/20/2024, 3:58 PM_
😅Davide Giuseppe Farella
05/20/2024, 3:59 PMval base: Base = One(…)
base.rename(newName)
would return Base
, no? 🤔ephemient
05/20/2024, 3:59 PMephemient
05/20/2024, 4:00 PMT
will be inferred to Base
Davide Giuseppe Farella
05/20/2024, 4:01 PMclass Something<T : Base>(
val t: T
) {
fun someFun() {
t.rename() <- would this be `Base` or `T`?
}
}
ephemient
05/20/2024, 4:03 PMDavide Giuseppe Farella
05/20/2024, 4:04 PMephemient
05/20/2024, 4:12 PMfun Base.rename(...) = when (val subject: Base = this) {
is One -> ...
Davide Giuseppe Farella
05/20/2024, 4:16 PMfun <T: Base> T.copying(block: Base.() -> Base): T = with(this) {
@Suppress("UNCHECKED_CAST")
block() as T
}
https://pl.kotl.in/-qGOD2BnS
We gotta trust the user to not do weird things -i.e. returning wrong T
-, but seems a fair compromise 🙂Klitos Kyriacou
05/20/2024, 5:21 PMBase
doesn't have a definition of copy
. Shouldn't this
be smart-cast to the corresponding One
or Two
?
when (this as Base) {
is One -> copy(name = newName)
is Two -> copy(name = newName)
} as T
Youssef Shoaib [MOD]
05/20/2024, 5:34 PMthis as Base
is the one getting smartcast against One
or Two
. I agree with you, though, the compiler should understand that this as Base
and this
are one and the samekqr
05/21/2024, 7:05 AMDavide Giuseppe Farella
05/21/2024, 7:07 AM