# Mark Needham

Thoughts on Software Development

## F#: Partial Function Application with the Function Composition Operator

In my continued reading of F# one of the ideas I’ve come across recently is that of partial function application.

This is a way of allowing us to combine different functions together and allows some quite powerful syntax to be written.

The term ‘currying’ is perhaps a better known term for describing this although as I understand they are not exactly the same.

Currying is where we return a function that has been partially applied, in such a way that we can chain together a group of functions with a single argument.

I first came across this idea with the forward piping operator when reading about Matthew Podwysocki’s FsTest project but there is an even cleaner way of chaining functions together using Function Composition.

The function composition operator (>>) is defined thus:

 > (>>);; val it : (('a -> 'b) -> ('b -> 'c) -> 'a -> 'c)

We take in two functions (‘a -> ‘b and ‘b -> ‘c) and one value (‘a).
We evaluate the first function (‘a -> ‘b) with the argument ‘a and then pass the result to the second function (‘b -> ‘c).

The way I understand this:

• The first function takes in ‘a (which is the 3rd argument passed to >>) and returns ‘b
• The second function takes in ‘b (which is the return value of the first function) and returns ‘c (which is the return value of >>)

Chris Smith perhaps best explains this as follows:

 > let inline (>>) f g x = g(f x) val inline ( >> ) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c

Given two functions (f, g) and a value x compute the result of f(x) and pass the result to g.

From my reading so far this operator makes it even easier to write code in a declarative way (although I suppose the functional programming approach does encourage that in the first place).

We can achieve a lot of this nice declarative style by using the forward piping operator (|>) but the function composition operator takes it one step further:

Say we want to take a list of numbers, square all of them and then only show the negative ones:

 let findOddSquares = List.map (fun x-> x*x) >> List.filter (fun x -> x%2 <> 0);;

If we did this using the forward piping operator it would read like this i.e. we need to explicitly define the list:

 let findOddSquares list = list |> List.map (fun x-> x*x) |> List.filter (fun x -> x%2 <> 0);;

It’s not that much more verbose but there’s less code for doing the same thing if we use the function composition operator. I still think the forward piping operator works nicely when we just want to switch the order of the function and the data though:

 > [1..10] |> findOddSquares val it : int list = [1; 9; 25; 49; 81]

As with all my F# posts, I’m still learning so please point out if I have anything wrong. Chris Smith has a closer to real life example of how to use partial function application that probably shows the benefits more than I have here.

* Update *

As pointed out in the comments I’m actually finding the odd squares not the negative ones as I originally posted.

Be Sociable, Share!

Written by Mark Needham

January 12th, 2009 at 10:22 pm

Posted in .NET,F#

Tagged with , , ,

• Torbjörn Gyllebring

It seems like you’re actually finding odd squares not negative ones.

Given that you could also phrase it like this:
let square x = x*x
let isOdd = x%2 0
let findOddSquares = List.filter (square >> isOdd)

• I am playing with F# as well…I wonder which one is faster. Have you compared the IL between the two?

I am going to try to write to test the performance difference between the two.

• Pingback: The only wrong way()

• Hi Mark. Looking for “partial function application” found your blog. Thanks.
Thought you might enjoy this “powerful and elegant” use —
This should also explain why the event handler does not need to take sender:object as the first argument – you can pass the canvas (which is the sender) as a first argument using partial function application in a statically typed way (so you don’t have to cast object to Canvas).  – T. Petricek
http://stackoverflow.com/questions/8978297/f-wpf-mousemove-params

PLH OOE Art Scott