Search code examples
recursionlambdakotlin

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?


Solution

  • 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.