Reading time: 5 minutes
Haskell has some beautiful constructs and really allows for very expressive code along with maintaining strong, static typing and purity. I’ve been taking a deep dive into Haskell and the more I learn about the language, the more I’m falling for it! There are some really beautiful ways to express functional programming concepts in this language.Function composition, especially when used with point free function references, is one of them.
So, what is function composition anyway?
This is a common approach in functional programming to build a pipeline of operations by combining functions to form new functions. Its very useful in reusing existing pure functions to produce a new transformation.
f(x) = x^2
g(x) = x + 2
Functions f and g can exist on their own but maybe we want a new function which takes a number, squares it and then adds 2 to it. We don’t want to create a whole new implementation for this when the transformation in question can simply be made up of two sub transformations, the functions f and g.
So, we create a new function, call it z, which takes, the number x, calls f on it and calls g on the result of that.
So we get
z(x) = g(f(x))
Simplified expression of composition in Haskell
Functional Programming languages usually each have their own special construct for expressing the composition of functions. This can be especially useful if there are multiple functions being composed as it cuts out the need for multiple groupings of expressions. For example, if we also have the functions,
h(x) = x * 3
k(x) = x / 4
and we decide we want a new transformation to square a number, add 2 to it, then multiply it by 3 and then divide it by 4,
we end up with a composition like this:
z(x) = k(h(g(f(x))))
I know this is just pseudocode but, even still, it is becoming hard to read! And also, bear with me. I know composing transformations as simple as arithmetic is a bit contrived and could be done with just one overall arithmetic expression. The example is deliberately contrived but if you imagine a pipeline with more complex transformations like, say, processing financial trades or something, being able to break an overall transformation up into small composable transformations becomes incredibly useful!
Haskell has a beautifully simple way of expressing function composition. Lets have a look and I’ll explain the Haskell code along the way.
module FunctionComposition where f x = x^2 g x = x + 2 h x = x * 3 k x = x / 4 z x = k . h . g . f $ x
In the Haskell code above I have declared the four functions, f, g, h and k that I showed earlier, along with the function z which is a composition of those four. I would usually write associated type signatures with every function I write in Haskell but I have left typing out of this example to focus on the function composition construct and also an explanation of Haskell typing definitely merits its own blog post!
The function declaration syntax in Haskell is, in itself, very concise and elegant. It is simply the name that the function is being bound to followed by a space and one or more parameters, each separated by spaces, followed by = and then the expression of the function body.
So, in the case of
f x = x^2
the name that the function is bound to is f, there is only one parameter and this is x and the expression of the function body is after the = and is
The function composition part is in the declaration of the function, z.
z x = k . h . g . f $ x
The composition is handled by the
in between each of the functions being combined together.
is in itself a function which takes which takes 2 functions, say (in pseudocode) g(x) and f(x) and returns a new function z(x) = g(f(x)). To compose up multiple functions is so simple and elegant with this simple composition function.
is just a function which applies what is on its left to what is on its right. It has the lowest precedence though so it means the function composed of f, g, h and k on its left is fully composed before being applied to x.
Also, if you prefer the reading of the sequence of transformations from left to right instead of right to left, you can simply add this just under the module declaration in the above Haskell code.
And now, we can use >>> instead giving
z x = f >>> g >>> h >>> k $ x
What’s this “point free” thing?
Point free means expressing functions without their arguments. This may sound kind of strange for people coming from OOP or other paradigms but it actually makes for code where the reader can concentrate on the transformation that is being expressed without the code being obscured by unnecessary argument names. It is made possible in functional programming because functions can be treated as first class values and they can be bound to names just like any other values.
So, say we compose z just from the functions g and f above, the Haskell function composition would be:
z x = g . f $ x
but the x argument serves no purpose here. All we need to do is bind to z, the function which is composed of g and f. A type signature (left out here as typing is a subject for another blog post) here would serve the purpose of expressing the type of the parameter that z expects when applied. So, using the point free style the functional composition is made even more elegant and can be expressed as:
z = g . f
and composing the 4 functions f, g, h and k simply becomes:
z = k . h . g . f
Now that really is quite beautiful!