What is currying in Kotlin, and how do you encode a two-argument function like add(a, b) as a curried function using returned lambdas?
answer
- One arg at a time, each returns the next function
- (Int) -> (Int) -> Int is right-associative
- Inner lambda is a closure over the outer param
- add(1)(2) chains the calls
- No built-in curry in Kotlin — nested lambdas
basics
~20 sCurrying turns a function that takes many arguments into a chain of functions that each take one argument and return the next function. You do it in Kotlin by returning a lambda from a lambda.
solid answer
~40 sCurrying transforms an n-argument function into a sequence of single-argument functions, each returning the next. In Kotlin there is no built-in `curry` operator; you encode it manually with nested lambdas. For `add(a, b)` you write a value of type `(Int) -> (Int) -> Int`: `val add: (Int) -> (Int) -> Int = { a -> { b -> a + b } }`. Calling `add(1)` returns a `(Int) -> Int` closure that has captured `a = 1`; calling `add(1)(2)` finally yields `3`. The inner lambda is a closure over the outer parameter. Kotlin's function-type syntax `(Int) -> (Int) -> Int` is right-associative, matching the nesting. Currying is rare in idiomatic Kotlin because default arguments and overloads usually solve the same need more readably.
code
kotlin · 5 linesval add: (Int) -> (Int) -> Int = { a -> { b -> a + b } }
val sum = add(1)(2) // 3
val addTen = add(10) // (Int) -> Int closure capturing a = 10
println(addTen(5)) // 15go deeper
Can state that currying breaks an n-arg function into single-arg functions and write the nested-lambda form with the correct (Int) -> (Int) -> Int type.
Explains right-associativity of -> and that the intermediate value is a closure capturing the first argument.
Notes Kotlin has no built-in currying and that default/named arguments are the idiomatic substitute; can reason about when currying actually pays off.
Frames currying as a building block for generic combinators/point-free pipelines and weighs its readability cost against Kotlin idioms in a shared codebase.
## What currying is **Currying** is the technique of rewriting a function that takes multiple arguments into a chain of functions that each take exactly **one** argument and return the next function in the chain, until the final one returns the result. The name comes from logician Haskell Curry. A normal two-argument function: ```kotlin fun add(a: Int, b: Int): Int = a + b ``` Its **curried** form is a function that takes `a` and returns *another function* that takes `b`: ```kotlin val add: (Int) -> (Int) -> Int = { a -> { b -> a + b } } val result = add(1)(2) // 3 val addOne = add(1) // (Int) -> Int, with a captured as 1 val three = addOne(2) // 3 ``` ## Reading the type The type `(Int) -> (Int) -> Int` means "a function from `Int` to (a function from `Int` to `Int`)". The `->` arrow is **right-associative**, so it groups as `(Int) -> ((Int) -> Int)`. That mirrors the nested lambdas exactly. ## Why it works: closures The inner lambda `{ b -> a + b }` is a **closure** — it captures the variable `a` from its enclosing scope. When you call `add(1)`, you create a new function object that remembers `a = 1`. This captured state is what makes currying useful: each application "locks in" one argument. ## How you invoke each stage - `add` is `(Int) -> (Int) -> Int` - `add(1)` returns `(Int) -> Int` - `add(1)(2)` returns `Int` You can also stop partway and store the intermediate function (`val addOne = add(1)`), which is the bridge to **partial application**. ## Idiomatic note Kotlin has **no built-in currying operator** (unlike Haskell, where every function is curried by default). You hand-roll it with nested lambdas. In practice Kotlin developers prefer **default arguments**, **named arguments**, and **overloads** for the same ergonomic goals, reserving currying for functional-style pipelines and generic combinators.
- What is the type of add(1) before you supply the second argument?(Int) -> Int — a single-argument function closing over a = 1.
- Why is the function type written (Int) -> (Int) -> Int and not ((Int) -> Int) -> Int?The arrow is right-associative, so it naturally means a function returning a function; the alternative would mean a function that takes a function as its argument — a different signature.
Like a vending machine that first asks for your coins, then hands you a second machine that asks which snack — one choice per step.
saying these in an interview costs you the question
- Confusing currying with overloading or with simply calling a function twice
- Thinking Kotlin has a built-in curry keyword/operator
- Writing the type as ((Int) -> Int) -> Int and calling it curried
- Not understanding that the inner lambda captures the outer argument via a closure