0
votes

I am having problems converting this chunk of Java to Kotlin:

Publishers.map(chain.proceed(request), response -> {
            if (request.getCookies().contains("SOME_VALUE")) { 
                response.cookie(request.getCookies().get(STATE_COOKIENAME).maxAge(0));
            }
            return response;
        });

The second parameter of the map method (note Publishers is not a collection) takes Function<T,R>. I have tried several solutions, including providing a lambda thus:

Publishers.map(chain?.proceed(request), {
        x: MutableHttpResponse<*>!,
        y: MutableHttpResponse<*>! -> print("It worked")
    })

but that results in:

Error:(32, 38) Kotlin: Unexpected token

Error:(33, 38) Kotlin: Unexpected token

Error:(31, 27) Kotlin: Type inference failed: fun map(publisher: Publisher!, mapper: Function!): Publisher! cannot be applied to (Publisher>!>?,(MutableHttpResponse<>, MutableHttpResponse<*>) -> Unit)

Error:(31, 56) Kotlin: Type mismatch: inferred type is (MutableHttpResponse<>, MutableHttpResponse<>) -> Unit but Function>!, MutableHttpResponse<>?>! was expected

and providing a method:

return Publishers.map(chain?.proceed(request), ::processCookie)

private fun processCookie(a: MutableHttpResponse<*>?) {
   print("something something something")
}

which results in:

Error:(31, 27) Kotlin: Type inference failed: fun map(publisher: Publisher!, mapper: Function!): Publisher! cannot be applied to (Publisher>!>?,KFunction1<@ParameterName MutableHttpResponse<>?, Unit>)

Error:(31, 56) Kotlin: Type mismatch: inferred type is KFunction1<@ParameterName MutableHttpResponse<>?, Unit> but Function>!, MutableHttpResponse<*>?>! was expected

For context I thought it would be fun to attempt this tutorial in kotlin.

1
The third solution was to leave that code as Java. - Gavin

1 Answers

2
votes

You do not specify the return type in the lambda, it is inferred by Kotlin. The last example did not work, because the return type of the function is Unit, which is void in Java. I would try the following:

return Publishers.map(chain?.proceed(request), ::processCookie)

private fun processCookie(a: MutableHttpResponse<*>?) : MutableHttpResponse<*>? {
   print("something something something")
   return a
}

It may also work if you write

return Publishers.map(chain?.proceed(request)) { 
  print("something something something")
  it
}

We use here the default parameter name of the Lambda in Kotlin - namely it. Kotlin compiler will infer types for you. It is also allowed in Kotlin to move the last lambda parameter of a function outside of brackets.

The last thing for the functional interfaces from Java, e.g. Function<T,R>. You may need to use the name explicitly, e.g.

return Publishers.map(chain?.proceed(request), Function<T,R> { 
  print("something something something")
  it
})

where T and R has to be substituted with the actual types