so no <changing the type of a member with copy()>?...
# language-evolution
o
so no changing the type of a member with copy()? is there an issue i can go vote? 🙂
h
Interessting idea, but how should it work? The compiler generates this copy method:
Copy code
data class C<T>(val t: T) {
    fun copyGenerated(t: T = this.t): C<T> = C(t)
    
    // your custom/expected copy method
    fun<R> customCopy(t: R = this.t): C<R> = C(t) // does not work, because T has no relation with R
}

fun a() {
    val c1 = C(t = "")
    val c2 = c1.copyGenerated() // default t = this.t (String)
    val c3 = c1.customCopy(t = 42) // usage works, because T is specified
    val c4 = c1.customCopy() // error: R is unknown 
}
But this does not work, because T has no relation with R, so type checking fails.
o
can’t say i’ve thought that far but it works here so i just thought why not
h
But does Scala support default arguments? This is the problem in the copy method.
o
yes it does
k
How about if, instead of default arguments (which is the cause of the problem) the customCopy was overloaded?
Copy code
data class C<T>(val t: T) {
    fun copyGenerated(t: T = this.t): C<T> = C(t)
    
    // your custom/expected copy method
    fun<R> customCopy(t: R): C<R> = C(t) // works
    fun customCopy(): C<T> = C(this.t)   // also works
}
The problem is that when you have N arguments, where N could be large, you would need 2^N overloads, so this solution is not scalable. It would be interesting to know how Scala implements this.
o
you can get an idea if you add
"-Vprint:typer"
to Extra Sbt Configuration in the Scastie Build Settings tab
it generates methods like
copy$default$1[A]
for the default values and passes those to each parameter to
copy
that were not explicitly given
a
you are looking for
map
rather than
copy
an object of type
C<T>
should always return the same type when copied, but can return a different type upon a mapping