Friday, February 12, 2010 11:03 AM
by
RickM
Get Started with F# via Higher order IEnumerable<T> extension methods in C#
The more I use F# the more I want to write my every day production C# code in a functional way. To this end, I’ve written a few higher order extension methods as the need arose. I wanted to take a moment and share them with you. I think that in seeing an implementation of these functions in C#, what they do becomes easy to understand.
Filter provides a new collection with unwanted items removed.
public static IEnumerable<T> Filter<T>(this IEnumerable<T> list, Predicate<T> predicate)
{
List<T> newList = new List<T>();
foreach (var item in list)
{
if (predicate(item))
newList.Add(item);
}
return newList;
}
Reduce boils down a collection into exactly one item of the collection’s containing type.
public static T Reduce<T>(this IEnumerable<T> list, Func<T, T, T> function)
{
var enumerator = list.GetEnumerator();
enumerator.MoveNext();
var last = enumerator.Current;
while (enumerator.MoveNext())
{
last = function(enumerator.Current, last);
}
return last;
}
Fold is much like reduce except that it boils the collection down into an instance of any type.
public static U Fold<T, U>(this IEnumerable<T> list, Func<T, U, U> function, U initial)
{
var enumerator = list.GetEnumerator();
var last = initial;
while (enumerator.MoveNext())
{
last = function(enumerator.Current, last);
}
return last;
}
Map takes one collection and returns another of the same length by applying a function to each element.
public static IEnumerable<U> Map<T, U>(this IEnumerable<T> list, Func<T, U> mapFunction)
{
List<U> newList = new List<U>();
foreach (var element in list)
{
newList.Add(mapFunction(element));
}
return newList;
}
While these four are a good subset to begin with, F# provides a much broader range of IEnumerable functionality. Also, while examples here build new lists, their F# counterparts often evaluate lazily and so are usable with very large, parallelized or even infinite sequences.
For a more detailed view with some F# and Linq code check out Matthew Podwysocki’s post on learning Functional C# from F# and LINQ. His example are actually lazy when appropriate and have precondition checks.