// WITH_RUNTIME // IGNORE_BACKEND_FIR: JVM_IR // java.lang.StackOverflowError // at Nat$Companion$invoke$1.next(kt36853_fibonacci.kt:40) ... fun box(): String { Nat( nil = 0, next = { this + 1 } ).run { val fib = fibonacci(10) if (fib != 89) return "Failed: $fib" } return "OK" } fun Nat.fibonacci( n: T, seed: Pair = nil to one, fib: (Pair) -> Pair = { (a, b) -> b to a + b }, i: T = nil, ): T = if (i == n) fib(seed).first else fibonacci(n = n, seed = fib(seed), i = i.next()) tailrec fun Nat.plus(l: T, r: T, acc: T = l, i: T = nil): T = if (i == r) acc else plus(l, r, acc.next(), i.next()) interface Nat { val nil: T val one: T get() = nil.next() fun T.next(): T operator fun T.plus(t: T) = plus(this, t) companion object { operator fun invoke(nil: T, next: T.() -> T): Nat = object: Nat { override val nil: T = nil override fun T.next(): T = next() } } }