Currying is a powerful concept in functional programming languages like Haskell. It refers to the process of transforming a function that takes multiple arguments into a sequence of single-argument functions. This technique allows for easier function composition and partial application.
To understand currying, let’s first look at a function that takes two arguments and returns their sum:
add :: Int -> Int -> Int
add x y = x + y
This function has a type ‘Int -> Int -> Int‘. It might appear like it’s a function taking two ‘Int‘ arguments and returning another ‘Int‘. However, in Haskell, there are no multi-argument functions. Every function actually takes just one argument and returns another function as a result. In this case, ‘add‘ is a function that takes an ‘Int‘ and returns a function of type ‘Int -> Int‘. So the type ‘Int -> Int -> Int‘ can be read as ‘Int -> (Int -> Int)‘.
Now let’s rewrite this function in a curried form:
addCurried :: Int -> (Int -> Int)
addCurried x = y -> x + y
‘addCurried‘ is now explicitly a function of one argument, returning another function that takes one argument. You can still use this function like ‘add‘:
ghci> addCurried 3 5
8
But how does this work? When we apply ‘addCurried‘ to its first argument, ‘3‘, it returns a lambda function, y − > 3 + y. By applying this lambda function to the second argument ‘5‘, we get the result ‘8‘.
This example might not seem very useful, but the power of currying comes from its ability to partially apply functions. Suppose you want to create a function that increments a given number by one:
inc :: Int -> Int
inc = addCurried 1
ghci> inc 5
6
By applying ‘addCurried‘ only to its first argument, you’ve created a new function, ‘inc‘, that takes a single ‘Int‘ argument and increments it by one. This partial application technique is very useful for composing functions and effeciently reusing code.
In summary, currying is a technique in Haskell that transforms multi-argument functions into sequences of single-argument functions. This allows for easier function composition and efficient code reuse with partial application. Here’s a visual representation of our example: