https://kotlinlang.org logo
d

dimsuz

05/15/2021, 12:07 PM
Hi! Why is type inference failing here? To my eyes it has all the info it needs to infer the type...
Copy code
class Builder {
  fun <R> build(action: (R) -> R): Builder = this
}

fun main() {
  val value = 3
  Builder()
    .build { value } // compiler error: not enough information to infer type variable R
}
That is: lambda is returning
Int
therefore
R
is
Int
UPD: this is kotlin 1.5.0
i

Ivan Krylov

05/15/2021, 3:09 PM
Because “value” is not explicitly “Int”, it can be at least a Double or Float as well
d

dimsuz

05/15/2021, 3:54 PM
no, it's
Int
. that's kotlin's default, it has no ambiguity in this case. If I add
val value: Int = 3
it highlights
: Int
as "redundant" and the error still stays. Even if I replace int with string, or whatever other type, it stays, so that's not it.
r

russhwolf

05/15/2021, 5:48 PM
I’m guessing it’s because there’s not enough info to infer the input parameter of the lambda. It seems to work if you change
action
to be
() -> R
or if you do
Builder().build { _: Int -> value }
d

dimsuz

05/15/2021, 6:29 PM
Indeed! But I wonder why is it so? I've reduced it to a simple function:
Copy code
fun <R> build(action: (R) -> R) = Unit

fun main() {
  val value: Int = 3
  build { value } // not enough information to infer type variable R
}
But here's an equivalent Haskell program and it compiles and runs perfectly. So it seems like a type inference limitation...
Copy code
build :: (a -> a) -> ()
build action = ()

main = do
  let value = 3
  return $ build (\_ -> value)
e

ephemient

05/15/2021, 6:37 PM
Kotlin has more type inference than Java but not as much as a full H-M system like Haskell (none of which work freely with polymorphism, so don't expect that)
l

lhwdev

05/16/2021, 6:07 AM
It seems
.build<Int> { value }
looks cleaner to me. There is
BuilderInference
, but I don't know if it can be applied here; afaik it infers type from value arguments.
e

ephemient

05/16/2021, 7:02 AM
for this case, yes.
.build { _: Int -> value }
is sometimes preferable if there are multiple type parameters and you only need to hint a single one (because
<>
forces you to write all of them)
👍 1
d

dimsuz

05/16/2021, 3:17 PM
I wonder can this be done at all in kotlin compiler, maybe I should file a feature request.
e

ephemient

05/16/2021, 6:06 PM
I think you're asking for https://youtrack.jetbrains.com/issue/KT-8138 although as a QoL improvement I'd like https://youtrack.jetbrains.com/issue/KT-13394 too
d

dimsuz

05/17/2021, 12:45 PM
Thanks, subscribed! I'll add my case to the second one. However. No, it doesn't look exactly like the second one. Will try to report a new one if I won't find existing issue.
6 Views