A Software Engineering Blog

by Nick Holmes

  Home  |   Contact  |   Syndication    |   Login
  11 Posts | 0 Stories | 6 Comments | 0 Trackbacks

News

Archives

Post Categories

OK, so you define a function that takes 2 parameters, but you actually get a function that takes 1 parameter, and returns a function that will take the second parameter and return the final result. Hmm, this raises lots of questions.

What happens if the function has more than two parameters?

>let f a b c = a + b + c

is of type

val f : int -> int -> int -> int

So we get a chain of functions, each one taking exactly one parameter, and returning a function that takes the next.

If there are more that 2 parameters, can I partially apply more than one at a time?

Following on from above, we can do:

>let g = f 1 2

val g : (int -> int)

>g 3

val it : int = 6

This looks like F# functions can just accept a subset of their arguments, but remember that as f returns a function, what is really happening is the equivalent of this:

let g = (f 1) 2

We are making a sequence of function calls. We could make the exact call like this:

((f 1) 2) 3

The consequence of this is that we can’t partially apply any sub-set of the arguments. We still have to call the function chain in the correct order, which partially apply the arguments strictly from left to right.

What happens to the partially applied arguments?

They are captured forever and immutably in the returned function.

let f a b = a + b

let g = f 1

let h = f 10

g will always return its argument plus 1, h always plus 10. f did not return the same function when called with different arguments.

Strange as this last point seems to those of us more used to C#, this notion of capturing values into functions does exist in C#. Anonymous delegates capture the values of variables from their declaring method. In C# 3.0, lambda functions are a simpler syntax for these anonymous delegates. Here is an example.

static void Main(string[] args)
{
    var g = f(1);
    var h = f(10);

    Console.WriteLine(”g(5) = {0}”, g(5));
    Console.WriteLine(”h(5) = {0}”, h(5));
    Console.WriteLine(”f(3)(5) = {0}”, f(3)(5));
}

static Func<int, int> f(int a)
{
    return new Func<int, int>(x => x + a);
}

Similar result, ugly code!

  • Share This Post:
  • Share on Twitter
  • Share on Facebook
  • Share on Technorati
posted on Tuesday, May 05, 2009 11:25 AM