Rash thoughts about .NET, C#, F# and Dynamics NAV.


"Every solution will only lead to new problems."

Friday, 27. January 2012


Partial application in F# and C#

Filed under: F# — Steffen Forkmann at 18:55 Uhr

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:

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: , ,

10 Comments »

  1. 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

  2. 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

  3. 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

  4. 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

  5. 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

  6. 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

  7. […] 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

  8. […] 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

  9. […] 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

  10. […] 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

RSS feed for comments on this post. | TrackBack URI

Leave a comment

XHTML ( You can use these tags): <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> .