Aug 3 2009

Functional programming examples

Category: zvolkov @ 19:44

In the series of Very Old News, I'm writing up some random examples of functional programming techniques.

First, let's see how we can define sequences using a function that produces next value in a sequence given a previous value:

public static class FunctionalExtensions
{
    //extension method that takes an initial value and a function that produces each subsequent value:
    public static IEnumerable<T> Sequence<T>(this T head, Func<T, T> lambda)
    {
        T current = head;
        while (true)
        {
            current = lambda(current);
            yield return current;
        }
    }
}

//then, somewhere else, use the new Sequence method:
foreach (var q in 0.Sequence(x => x + 1).Take(10))
{
    Console.WriteLine(q);
}
Of course we could just use Enumerable.Range, but our Sequence gives us ability to define geometric progressions or even non-numeric sequences.

Next, let us see how we can build another funky alternative to the for loop:
public static class FunctionalExtensions
{
    //a Ruby-inspired method that executes its argument specified number of times:
    public static void Times(this int count, Action<int> action)
    {
        for (int i = 0; i < count; i++) action(i);
    }
}

//and its usage:
5.Times((i) => Console.WriteLine(i));
Next, let's look at a very weird way of adding up numbers:
//this is a function that takes an int and returns second function that takes another int and adds it to the first one:
public static Func<int, int> Add(int left)
{
    return (right) => left + right;
}

//here's how we can use it:
int sum = Add(2)(3); //returns 5
Finally, classic map & reduce functions (equivalents of LINQ's Select and Aggregate). Map is a simple f(x) while Reduce takes a sequence and aggregates it into a single value:
public static IEnumerable<R> Map<T, R>(this IEnumerable<T> input, Func<T, R> mappingFunction)
{
    foreach (var i in input)
        yield return mappingFunction(i);
}

public static T Reduce<T>(this IEnumerable<T> input, Func<T, T, T> reduction)
{
    T currentValue = default(T);

    foreach (var i in input)
        currentValue = reduction(currentValue, i);

    return currentValue;
}

//putting it all together
var sum = 1.Sequence(x => x * 2).Take(10).Map(x => x + 1).Reduce((x, y) => x + y);
This should provide enough background for my link of the day: Introduction to Google MapReduce for .NET Developers

Tags:

Comments

Add comment


(Will show your Gravatar icon)

biuquote
  • Comment
  • Preview
Loading