Neglecting parameters when casting a function that returns Unit

Is there a way to cast a lambda say () -> Unit to a (String) -> Unit? Specifically in constructors?

Currently, my get around is just wrapping it with another lambda as follows

val x: () -> Unit = { println("x has fired") }
val xMapped: (String) -> Unit = { x() }

Why does the compiler not neglect the argument in this case so I can do
val xMappedBetter: (String) -> Unit = x // Can't cast!

In fact, if it was really smart, and you didn’t have duplicated parameters couldn’t it even handle
(String, Int, Double, Float) -> Unit to (Float) -> Unit or (Int, Float) -> Unit?

Perhaps I am naive, or perhaps a solution already exists. But overloading a constructor 5 times to wrap a lambda seems unnecessary.

It is for the same reason we can’t do this:

fun foo() = ...

foo("hello")

It is a different kind of a function. { x() } is a correct solution as it is clear it creates a different lambda type.

If you like, you can always create a simple util for yourself:

fun <R> (() -> R).withIgnoredArgs1(): (Any?) -> R = { invoke() }

val x: () -> Unit = { println("x has fired") }
val xMappedBetter: (String) -> Unit = x.withIgnoredArgs1()

However, I’m not entirely convinced about this.

1 Like