M Krane
M Krane

Reputation: 169

Kotlin - How to recursively call a lambda function

I'm trying to re implement the linrec function from here in Kotlin. Here is what it currently looks like in Kotlin:

fun <A, B> linrec(indivisible: (List<A>) -> Boolean,
                  value: (List<A>) -> B,
                  divide: (List<A>) -> List<List<A>>,
                  combine: (A, B) -> B
                  ) : (List<A>) -> B {
  val myfunc: (List<A>) -> B = { input ->
    if (indivisible(input)) {
      value(input)           
    } else {
      val split = divide(input)
      val left = split[0][0]
      val right = myfunc(split[1])  // Error
      combine(left, right)   
    }
  }
  return myfunc
}

IntelliJ gives me the following errors, when I try to run the code:

Error:(40, 19) Kotlin: Unresolved reference: myfunc

My question is: How do I make a lambda function call itself?

Upvotes: 8

Views: 5614

Answers (1)

voddan
voddan

Reputation: 33749

You don't call a lambda ("anonymous function") from inside itself. That's what functions are for:

fun <A, B> linrec(indivisible: (List<A>) -> Boolean,
                  value: (List<A>) -> B,
                  divide: (List<A>) -> List<List<A>>,
                  combine: (A, B) -> B
                  ) : (List<A>) -> B {

  fun myfunc(input: List<A>): B {     // rearranged things here
    return if (indivisible(input)) {  // added `return`
      value(input)           
    } else {
      val split = divide(input)
      val left = split[0][0]
      val right = myfunc(split[1])
      combine(left, right)            // *   
    }
  }
  return ::myfunc
}

Now this is exactly the code you've wrote, but it does not compile. On the line I marked with * kotlinc says Type mismatch: inferred type is B but A was expected.

P.S. I have no idea what that code is doing, so I only fixed the compilation error you've asked about.

Upvotes: 7

Related Questions