David
David

Reputation: 286

Kotlin generic type inference failed

I am translating some Scala code into Kotlin. This is based on code in the book Functional Programming in Scala. Here is a direct translation of the code into Kotlin:

data class State<S, out A>(val run: (S) -> Pair<A, S>) {
    fun <B> flatMap(f: (A) -> State<S, B>): State<S, B> = State { s ->
        val (a, s1) = run(s)
        f(a).run(s1)
    }

    fun <B> map(f: (A) -> B): State<S, B> =
            flatMap { a -> unit(f(a)) }

    companion object {
        fun <S, A> unit(a: A): State<S, A> =
                State { s -> a to s }
    }
}

The call to unit(f(a)) in map is causing the following error:

Error:(8, 28) Kotlin: Type inference failed: Not enough information to infer parameter S in 
    fun <S, A> unit(a: A): State<S, A>
Please specify it explicitly.

Since the types are all generic, and it knows that it is the generic type S, I have no clue what type to specify. What is wrong with this code?

Thank you in advance.

Upvotes: 1

Views: 2101

Answers (1)

marstran
marstran

Reputation: 28066

The S type parameter given to the unit function is not necessarily the same as the S type in State. You therefore need to specify it explicitly when you call the unit function. Like this:

fun <B> map(f: (A) -> B): State<S, B> =
        flatMap { a -> unit<S, B>(f(a)) }

Edit: Actually, the type could be known from the return type of map, but it seems like the type inference in Kotlin isn't strong enough to figure it out by itself.

Upvotes: 1

Related Questions