// WITH_STDLIB 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() } } }