Fun(c) with C# 3.0

Uncategorized 9 October 2007 | 1 Comment

Looking through the list of predefined (or, in Microsoft’s parlance, standard) query operators defined in C# 3.0, there is one that stands out as missing: the ‘map’ function. However, with the new query expression syntax, this is trivial to define:

public static IEnumerable<T> Map<F,T>(Func<F,T> func, IEnumerable<F> source)
{
    return
        from it in source
        select func(it);
}

Actually, it’s trivial to implement without the new syntax (although I’ve left in Func because it’s nicer than defining a separate delegate):

public static IEnumerable<T> Map<F,T>(Func<F,T> func, IEnumerable<F> from)
{
    foreach (F it in from)
        yield return func(it);
}

But why stop at map? We can also define a fold:

public static T FoldL<F, T>(Func<T, F, T> func, IEnumerable<F> source, T init)
{
    T last = init;
    foreach (F it in source)
        last = func(last, it);
    return last;
}

Or the non-empty-list variant. This is made easier through the query operator Skip:

public static T FoldL1<T>(Func<T, T, T> func, IEnumerable<T> source)
{
    T last = source.First();
    foreach (T it in source.Skip(1))
        last = func(last, it);
    return last;
}

Finally, a simple compose operator for sticking two functions together, again using the nicer syntax to make this simple:

public static Func<X,Z> Compose<X,Y,Z>(this Func<Y,Z> second, Func<X,Y> first) {
    return x => second(first(x));
}

Example

A simple example including functionality from each part above (I put everything into an FFC utility class):

int[] numbers = { 1, 2, 3, 4, 5 };
Func<int, int> addOne = n => n + 1;
 
foreach (var k in FFC.Map(addOne, numbers))
    Console.Write(k + " ");
Console.ReadLine();
 
Func<int,int> addTwo = addOne.Compose(addOne);
 
foreach (var k in FFC.Map(addTwo, numbers))
    Console.Write(k + " ");
Console.ReadLine();
 
var sum = FFC.FoldL((x, y) => x + y, numbers, 0);
Console.Write(sum + " ");
Console.ReadLine();

Tagged in , , , , ,

One Response on “Fun(c) with C# 3.0”

  1. Edward Kmett says:

    Map in c# is present as the Select extension method.

Leave a Reply