sunflower20
sunflower20

Reputation: 499

Invoke lambda with parameter/s in a higher order function

I am novice to functional programming in java/kotlin and do some practice. Just wonder how can I pass parameters of lambda when invoking it. For example, here to call someMethod I need to pass an Int parameter.

fun lambdaTest( someMethod: (Int) -> Boolean){
   someMethod()
}

How that can be done? The answer may be very simple, I just didn't find it anywhere, in the documentation there were only examples with lists, in case of which the answer is clear:

fun <T, R> List<T>.map(transform: (T) -> R): List<R> {
    val result = arrayListOf<R>()
    for (item in this)
        result.add(transform(item))
    return result
}

Upvotes: 1

Views: 1535

Answers (2)

Thibault Seisel
Thibault Seisel

Reputation: 1257

Think of (Int) -> Boolean as being equivalent to the following interface (in fact, that's actually what is compiled on the JVM) :

interface Function<I, O> {
    fun inkoke(param: I): O
}

I is the type of the input parameter, O is the type of the output type (returned value).

All lambda in Kotlin are in fact a shorthand syntax for defining an object with a single method invoke with a given number of parameters and a return type. Let's rewrite your high-order function taking this into account.

fun lambdaTest(someMethod: Function<Int, Boolean>) {
    // Call invoke with an Int paramater. This returns a Boolean.
    val isTheAnswerOfTheUniverse = someMethod.invoke(42)
}

Now, we call this method :

// We can pass an anonymous class as the parameter
lambdaTest(object : Function<Int, Boolean>() {
    override fun invoke(param: Int): Boolean {
        println("Lambda called with number: $param")
        // Prints "Lambda called with number: 42"
        return param == 42
    }
})

This is the same with (Int) -> Boolean. The only difference is syntax: as Kotlin is also a functional language, it offers syntactic sugar to improve readability and reduce boilerplate, such as

  • a dedicated syntax for defining functions as variable
  • .invoke can be omitted (because it is an operator overload)
  • a dedicated syntax for defining lambda, just like Java 8 has (Kotlin's uses curly brackets).
  • If a lambda is the last parameter of a high order function, then lambda can be expressed outside of brackets.

Here is the equivalent with lambda syntax:

fun lambdaTest(someMethod: (Int) -> Boolean) {
    val isTheAnswerOfTheUniverse = someMethod(42)
}

fun main(args: Array<String>) {
    lambdaTest { param ->
        println("Lambda called with number: $param")
        // Prints "Lambda called with number: 42"

        // The result of the last expression is returned
        param == 42
    }
}

Upvotes: 2

icarumbas
icarumbas

Reputation: 1815

Here you need to pass function that takes Int as argument and returns Boolean.

lambdaTest { int ->
     int > 0 // can be also changed to it
}

Here we return true if Int parameter is more than 0.

If you want more parameters:

fun lambdaTest( someMethod: (Int, String) -> Unit){ // Unit means do not return anything
     someMethod(1, "Kotlin")
}

And call it:

lambdaTest { int, string ->
    println("Passed Int: $int, and String: $string as parameter")
    // Output = Passed Int: 1, and String: Kotlin as parameter
}

Upvotes: 2

Related Questions