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: