Function curry - what and why!

in #programming7 years ago

Chances are that if you work in imperative languages you will not have encountered curried functions. Thought I would quickly explain what they are, what they are good for and why you might want to use them.

The concept is actually very simple and in many functional languages the standard means of calling a function.

Take this simple function:

int Add(int lhs, int rhs)
{
    return lhs + rhs;
}

In many functional language functions can only take one argument and must return a result. So the Add function above becomes the following:

Func<int, int> Add(int lhs)
{
    return rhs => lhs + rhs;
}

var result1 = add(1)(5); // Equals 6;

var add1 = Add(1);
var result2 = add1(5); // Equals 6

Add is now a function that takes one argument and returns a function with the remaining argument. If the function takes three arguments you have a function that returns a function that returns a function that returns a result.

You are probably asking why you would want this. A good example of a use case in an imperative language would be dependency injection. Take the following class:

class UserList
{
    private DBConnection _connection;

    public UserList(DBConnection connection)
    {
        _connection = connection;
    }

    public IEnumerable<User> Where(Func<User, bool> predicate)
    {
        // uses connection to get users
        return users.Where(user => predicate(user));
    }
}

This sort of pattern is perfect for a curried function, an object that takes dependency details in the constructor and then has one function. It can be expressed as follows:

public Func<Func<User, bool>, IEnumerable<User>
    UserList(DBConnection connection)
{
    return predicate =>
    {
        // uses connection to get users
        return users.Where(user => predicate(user));
    }
}

So far less code to read and understand, what about usage:

var userList = new UserList(connection);
var users = user.Where(user => user == "Bob");

var usersWhere = UserList(connection);
var users = usersWhere(user => user == "Bob");

// or even
var userList = UserList(connection)(user => user == "Bob"); 

No real overhead on usage, so overall win. You can also use it to make code less noisy. Say you have a function with a few arguments and you normally call it with the same values in the first couple of arguments. You simply restructure it:

public Func<object, int> MyFunc(object commonArg1, object commonArg2)
{
    return differentEachTimeArgument => 
    {
        // do the thing
        return result;
    }
}

You need a language that supports lambda for this to work, but that is becoming more common by the day. Many C style languages have embraced lambda including C++. Hopefully this makes you start to think a little different about what a function is and how you can write them.

Happy coding

Woz

Sort:  

I love how in Haskell, function application is defined as ($), and I love how (,) :: a -> b -> (a,b)

I want to love Haskell, such a beautiful language. But for me it has such a high cognitive workload to work with. F# is my functional home, a little more practical as hooked into the whole .NET platform :)

@royrodgers has voted on behalf of @minnowpond. If you would like to recieve upvotes from minnowponds team on all your posts, simply FOLLOW @minnowpond.

        To receive an upvote send 0.25 SBD to @minnowpond with your posts url as the memo
        To receive an reSteem send 0.75 SBD to @minnowpond with your posts url as the memo
        To receive an upvote and a reSteem send 1.00SBD to @minnowpond with your posts url as the memo

Coin Marketplace

STEEM 0.16
TRX 0.15
JST 0.029
BTC 57190.65
ETH 2409.68
USDT 1.00
SBD 2.28