Swifty function currying

Function currying is something I wanted to dig into for some time now, and finally I found a good time for it, especially now, after some changes introduced to the syntax in Swift 3.

What is function currying?

What is function currying (in general and in Swift)?

If you want to get a full definition, see Wikipedia. In short, function currying lets us write code that translates a function taking two arguments, into a function taking one argument, and returning a function taking the next argument (and so on for 2, 3, 4, … arguments).

It might not sound super clear yet, so let’s take a look at some examples.

func multiplyTwoNumbers(_ a: Int, _ b: Int) -> Int {
    return a * b

multiplyTwoNumbers(2, 3) //result: 6

Super simple, takes two Integers and returns result of their multiplication. What we have here is a 2 argument function that we will transform (as in definition), into function taking only one argument, returning another function, taking the second argument and returning an Integer.

In pseudo-code it would be something like:

function(a, b) -> c
function(a) -> (function(b) -> c)

You could ask - how is that useful? Well, it allows for this newly created (curried) function to be evaluated over a period of time, with each call passing only a subset of the arguments (and saving each call result on the way if needed).

So looking at our previous example, we could translate it into curried version like this:

func multiply(_ a: Int) -> (Int) -> Int {
    return { b in a * b }

multiply(2)(3) //result: 6

At this point, there’s still no real advantage, and we have this funky syntax, which is not obvious when you see it for the first time. But like I mentioned earlier, it allows us to evaluate it over time, and save each call result on the way.

let multiplyBy10 = multiply(10) 
//result: function that will multiply its argument by 10

let multiplyBy5 = multiply(5) 
//result: function that will multiply its argument by 5

let multiplyBy2 = multiply(2) 
//result: function that will multiply its argument by 2

Now you can call it like any other function:

let x = multiplyBy10(2) //result: 20
let y = multiplyBy5(2) //result: 10
let z = multiplyBy2(2) //result: 4

If we wanted to achieve same thing without currying, we would have to write a new function, for every first argument combination, like this:

func multiplyBy10(_ a: Int) -> Int {
    return a * 10

func multiplyBy5(_ a: Int) -> Int {
    return a * 5

func multiplyBy2(_ a: Int) -> Int {
    return a * 2

Much more writing, error-prone (most probably would implement it by copy-pasting) and when you know what function currying is, there’s no real difference in readablity (in my opinion).

Transforming standard functions into their curried versions

So far, we’ve been able to transform our own two-argument function into curried one. That’s quite easy, as we just rewrote it from scratch. Lets try to do something more complicated - tranform in a similar way UIColor.init(red: green: blue: alpha:) function, which we cannot modify directly in the source code.

How can we create curried function out of one that’s not curried? We need to implement a function that takes an existing function as a parameter (the one we want to transform) and returns a curried wrapper around it.

Before we go with UIColor’s init function, we will start by transforming our own multiplying function. To do this, we will create a function that takes (Int,Int)->Int function as an argument and returns a curried wrapper around it.

func curriedVersion(f: @escaping (Int, Int) -> Int) -> (Int) -> (Int) -> Int {
    return { a in { b in f(a,b) } }

(What is @escaping keyword? For more info I encourage you to visit Apple docs, but in short – we use it to mark a closure that will not be invoked directly by function taking this closure as an argument. In our case, we don’t call f function directly, we just pass it around and return it to be called later)

As we see, our curriedVersion function, takes as an argument a function (that matches multiplyTwoNumbers signature) and returns a function, that returns a function, that returns an Integer (I know it might be hard to follow, but bare with me).

Originally, our curried function multiply returned a function, that took one argument and returned an Integer. Because we’re transforming a function here, we need a wrapper around it. Let’s take a look again at pseudo-code:

Standard function taking two arguments and returning a number

standardFunction = function(a,b) -> c

Curried function that takes one argument and returns a function taking second argument, and returning a number

curriedFunction = function(a) -> (function(b) -> c)

How do we make curriedFunction out of standardFunction? We create a wrapper around it

transformingFunction = function(standardFunction) -> curriedFunction

If we now substitute function names with their definitions we get

transformingFunction = function(function(a,b) -> c) -> function(a) -> (function(b) -> c)

which looks similar to

func curriedVersion(f: @escaping (Int, Int) -> Int) -> (Int) -> (Int) -> Int

Ok, so how do we use our transforming function? We just call it by passing to it our old multiplyTwoNumbers function.

let curriedMultiply = curriedVersion(f: multiplyTwoNumbers)

Transforming UIColor.init() into curried function

Ok, now that we successfully transformed a 2 arguments function into its curried version, let’s go back to our goal - transforming UIColor.init(red: green: blue: alpha:) function that takes 4 arguments (as I mentioned earlier – same can be applied to any 2+ argument function).

func transformColorInit(f: @escaping (CGFloat, CGFloat, CGFloat, CGFloat) -> UIColor) -> ((CGFloat) -> (CGFloat) -> (CGFloat) -> (CGFloat) -> UIColor) {
    return { red in { green in { blue in { alfa in f(red, green, blue, alfa) } } } }

Might look hard to read, but it’s quite simple - our transformColorInit takes as an argument function that matches the signature of UIColor.init(red: green: blue: alpha:) and it returns a function that takes a float and returns a function, that takes a float and returns a function, that takes a float and returns a function, that takes a float and returns a color.

General rule is – you strip away one argument at a time.
If your initial function takes 2 arguments - you will have function returning a function 2 times.
If it takes 4 arguments (like UIColor.init(...)), you will have function returning a function 4 times etc.
Other than the syntax of it looking a bit weird, I think it should be quite easy to understand.

How do we use our transformer now? As before, we just call it, by passing to it UIColor.init(...) function.

let curriedInit = transformColorInit(f: UIColor.init(red: green: blue: alpha:))

(notice that we need to pass full signature of init function – it’s because UIColor has more than 1 init function taking 4 CGFloat arguments)

Now we can e.g. create a function, that will be creating red color with different values of alpha channel (passed as an argument).

let createRedWithAlfa = curriedInit(1)(0)(0)

let red05 = createRedWithAlfa(0.5)
let red02 = createRedWithAlfa(0.2)
let red09 = createRedWithAlfa(0.9)

Of course, you’re not limited to just last argument, you could also make a function taking 2 or 3 arguments if you needed to:

let createBlueColorWithAlpha = curriedInit(0)(0)

let semiTransparentBlue = createBlueColorWithAlpha(1)(0.5)
let solidBlue = createBlueColorWithAlpha(1)(1)

Generic tranforming function

Do we need to write a different transforming function for every function that we want to transform? Fortunately, the answer is NO.

We can use the power of Swift’s generics and write a generic function, that will take as an argument function with non-specified argument types (can be Int, Float, String, Class type etc) and return its curried version.

For 4 argument function (like UIColor.init(...)) it could look like this:

public func curry<A, B, C, D, E>(_ function: @escaping (A, B, C, D) -> E) -> (A) -> (B) -> (C) -> (D) -> E {
    return { (a: A) -> (B) -> (C) -> (D) -> E in { (b: B) -> (C) -> (D) -> E in { (c: C) -> (D) -> E in { (d: D) -> E in function(a, b, c, d) } } } }

It is a generic function with 5 different placeholder types – 4 of them for arguments of passed function and 1 for its return type. Of course, nothing stops us from passing a function that has all 4 arguments of the same type.

let createRedWithAlfaV2 = curry(UIColor.init(red: green: blue: alpha:))(1)(0)(0)

let red01 = createRedWithAlfaV2(0.1)

Code for curry function was written by guys from thoughbot – feel free to take a look and see an example for function transforming a function taking 20 arguments :)

That’s it for today. You should know what function currying is, how to use it and how to transform any 2+ argument function into its curried version. If you have any questions – let me know in comments!

Sources (I recommend you to read first 3 positions, they did help me to understand better what function currying is!):

Related Posts

GitHub Pages and Automatic Deployment

Looking for a free website hosting and automatic deployment after source code changes? Try GitHub pages and Wercker!

Credit Card Validation

Credit Card validation isn't as hard as it looks -- and you can add it to your app in a few minutes only!

Pyramid of Doom Updated (Swift 3)

Since last posts about using `let` and `guard`, Swift 3 came out and changed a few things here and there. Let's see what's new!

Dealing with Swift's Pyramid of Doom

Today we continue topic of avoiding Swift's "Pyramid of Doom" that we started in previous post about `guard` statement.

Let and guard statements in Swift

Swift 2 was announced in June, soon to be a year ago. Still, some of the concepts it introduced are new to many iOS developers.