Type inference when map with generic function


#1

Hi !

here is my situation:

open class A {
    fun <T:A> subst(data:Map<String, String>) : T {
        return this.clone().doSubst(data) as T //I know this looks strange
    }
}

class B : A() {
     fun doSomethingElse() {}
}

fun main(args: Array<String>) {

    val coll:List<B> = listOf(B(),B(),B())
    val data = mapOf("x" to "y")
    val coll1:List<B> = coll.map { it.subst(data) } // type inference failed! (even with explicit :List<B>)
}

but if I define:

fun <T:A> T.subst2(data:Map<String, String>) : T {
    return this
}

then this works fine:

fun main(args: Array<String>) {

    val coll:List<B> = listOf(B(),B(),B())
    val data = mapOf("x" to "y")
    val coll1 = coll.map { it.subst2(data) } // type inference success! even without (:List<B>).
}

So, the extension function ‘subst2’ have an advantage having a chance to capture the type of receiver. It would be great to have some way for member function ‘subst’ to specify to capture (when it possible) the type of a subclass e.g.:

open class A {
        fun This.subst(data:Map<String, String>) : This {
            // do something with this
            return this
        }
}

I know this is a syntax of extension member function but I meant to capture the type of an original receiver (probably another syntax could be elaborated).

The example of potential usage is chaning:

val b = B()

b.subst(data).subst(data1).doSomethingElse()

P.S. Sorry if this thing is already discussed somewhere or is a completely crap.


#2

This type for members is unlikely to be supported, currently you have to resort to extension functions to gain similar functionality.
See also this thread.


#3

Well, I see.