Today I had a conversation on twitter about partial application and type inference in F#. Partial application is a very important and useful concept and there are a lot of resources out there. Here is a short list of related material:

- Uncovering the Unknown: Principles of Type Inference (video)
- Wikipedia: Currying, Partial application, Type inference
- StackOverflow: What is the difference between currying and partial application
- HaskellWiki: Partial application
- F# BootCamp Q&A on this blog

I promised to show a small sample and I hope this clarifies some of my points on twitter. Let’s consider a multiplication function in C#:

This function allows us to compute the product of two ints. But what can I do when I need a function which doubles its input? The solutions is easy: I just create a new function:

And when I need a function which triples its input? Same thing, just create another method. But can we do better?

Letâ€™s transform the multiplication function into the curryied version. The transformation process is very easy once you see the pattern. Itâ€™s actually possible to write a function which curryies another function, but thatâ€™s something for another post. Anyway, hereâ€™s the curryied version:

It’s a little bit noisy with all the funky Funcs, but Ok. We can still write the double function in terms of multiply:

And of course we can use multiply directly (which might look a bit weird at first):

But we can also use it in another way, which we couldn’t really do before:

How cool is this? We just applied a single parameter and we got a new function without writing any method declarations. Unfortunately we wrote a lot of weird type declarations in order to get here, but hey.

Letâ€™s move to a language which has type inference. Hereâ€™s the uncurryied version of multiply in F#:

The type signature tells us, that we have to give it a tuple of ints and then we get an int back. Thatâ€™s exactly the same as in C#. Notice that we think about x1,x2 as only one parameter â€“ a tuple. How can we get to the curryied form? It couldnâ€™t be easier: just remove the parentheses and youâ€™re done:

As you can see the type signature changes a little bit. The * is now just another arrow. This means we have basically the same as Func<int, Func<int, int>> but in a much nicer syntax. There is also another way to write this:

This looks like the C# version, but notice how nicely the arrows align to the type signature. If we want to use the multiply function than we can write something like this:

Itâ€™s also very easy to create partially applied functions:

And finally the point which made me write this post. There is a simple rule: whenever we have the same parameter as the last parameter of the left and the right side of a function definition, we can remove it. This leads us to:

Isn’t this beautiful?

Tags: Currying, F#, partial application
Thanks a lot for this superb explanation! It actually is a very cool example on why the type inference is so important in FSharp, imho.

Thanks to you, I learned partial application today. Thanks to this blog post, I understand the concept better now. You are doing a great job!

Comment by Ilker Cetinkaya — Friday, 27. January 2012 um 20:14 Uhr

Yes, it is. Cool stuff.

To my understanding the difference between partial application and currying. Your sample is “currying”, right? Your functions returns functions with one parameter. An easy sample of partial application functions can be

Func f = (a,b) => a + b;

Func inc = a => f(a,1);

Console.WriteLine(inc(5));

Output: 6

Cheers,

Mike

Comment by Mike Bild — Friday, 27. January 2012 um 20:16 Uhr

Hi Mike,

currying is the process of transforming a function with tupled parameters into a function with one parameter less which returns another function.

In a function like F# you would usally just write the function in it’s curryied form. In C# you would like to write it just like the first version and use a higher-order function called “curry” to get the second form.

Partial application is just the usage of such a “curryied” function. I apply one parameter and get a function back.

Makes this any sense?

Cheers,

Steffen

Comment by Steffen Forkmann — Friday, 27. January 2012 um 20:31 Uhr

An interesting exception to “whenever we have the same parameter as the last parameter of the left and the right side of a function definition, we can remove it”: the Y-combinator as described in http://stackoverflow.com/questions/2003225/rosetta-stone-y-combinator

Try removing the x from the definition, and not only do you get a y function with a different signature, but it also turns it into a stack-overflow generator ðŸ˜‰

Comment by Johann Deneux — Friday, 27. January 2012 um 21:26 Uhr

By the way, apologies if I’m scaring anyone with the y-combinator. I still don’t quite get it and that hasn’t stopped me from being productive with F#.

Comment by Johann Deneux — Friday, 27. January 2012 um 21:28 Uhr

Hi Johann,

nice exception. Didn’t know that, but it makes perfectly sense.

Seems you’d have to give type hints for f in order to remove x.

Cheers,

Steffen

Comment by Steffen Forkmann — Saturday, 28. January 2012 um 6:58 Uhr

[…] last blog post was yet another introduction to Currying and Partial application. Now I want to put the focus more […]

Pingback by Why do we need partial application? – Part 1 of n – Fluent interfaces and piping » Rash thoughts about .NET, C#, F# and Dynamics NAV. — Sunday, 29. January 2012 um 10:36 Uhr

[…] Partial application in F# and C# and Why do we need partial application? â€“ Part 1 of n â€“ Fluent interfaces and piping (Steffen Forkmann) […]

Pingback by Dew Drop – January 29, 2012 (#1,253) | Alvin Ashcraft's Morning Dew — Monday, 30. January 2012 um 2:34 Uhr

[…] Partial application in F# and C# […]

Pingback by Currying and uncurrying in C# and F# » Rash thoughts about .NET, C#, F# and Dynamics NAV. — Monday, 30. January 2012 um 17:00 Uhr

[…] Partial application in F# and C# […]

Pingback by Why do we need partial application? – Part 2 of n – Simulating type classes in C# and F# » Rash thoughts about .NET, C#, F# and Dynamics NAV. — Tuesday, 31. January 2012 um 16:49 Uhr