Unit
is actually a type that has exactly one value (the value is Unit
itself; also, this is why it is named Unit
). It corresponds to void
in Java, but it's not the same.
Kotlin compiler treats functions with no declared return value as Unit
-returning functions, and return Unit
can also be omitted. This is why { }
is a Unit-returning function.
But this is not applied to arguments. To be strict, when you declare a function with Unit
argument or (Unit) -> Unit
function variable, you have to pass an argument of type Unit
at call site. The only value to pass is Unit
.
A lambda with no specified arguments like { doSomething() }
is treated both as a function with no arguments and as a function with single implicit argument it
. You can use { }
both as () -> Unit
and (Unit) -> Unit
.
As to the call site, as said above, Unit
has to be passed:
val f: (Unit) -> Unit = { println("Hello") }
f(Unit) // the only valid call
Whereas () -> Unit
functions do not need an argument to be passed:
val f: () -> Unit = { println("Hello") }
f() // valid call
In your example, type inference happens as follows:
fun <T, U> process(t: T, call: (U) -> Unit, map: (T) -> U) = call(map(t))
fun <T> processEmpty(t: T, call: () -> Unit) = process(t, call, {}) // error
map: (T) -> U = { }
, thus a replacement for U
is Unit
returned from { }
.
- Therefore
call
should be (Unit) -> Unit
.
call: () -> Unit
which is not the same to (Unit) -> Unit
, as stated above. Error.