Challenge: Neater way of currying or partially applying C#4's string.Join
Posted
by Damian Powell
on Stack Overflow
See other posts from Stack Overflow
or by Damian Powell
Published on 2010-04-17T14:30:37Z
Indexed on
2010/04/17
14:33 UTC
Read the original article
Hit count: 467
Background
I recently read that .NET 4's System.String class has a new overload of the Join method. This new overload takes a separator, and an IEnumerable<T>
which allows arbitrary collections to be joined into a single string without the need to convert to an intermediate string array.
Cool! That means I can now do this:
var evenNums = Enumerable.Range(1, 100)
.Where(i => i%2 == 0);
var list = string.Join(",",evenNums);
...instead of this:
var evenNums = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.Select(i => i.ToString())
.ToArray();
var list = string.Join(",", evenNums);
...thus saving on a conversion of every item to a string, and then the allocation of an array.
The Problem
However, being a fan of the functional style of programming in general, and method chaining in C# in particular, I would prefer to be able to write something like this:
var list = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.string.Join(",");
This is not legal C# though. The closest I've managed to get is this:
var list = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.ApplyTo(
Functional.Curry<string, IEnumerable<object>, string>
(string.Join)(",")
);
...using the following extension methods:
public static class Functional
{
public static TRslt
ApplyTo<TArg, TRslt>(this TArg arg, Func<TArg, TRslt> func)
{
return func(arg);
}
public static Func<T1, Func<T2, TResult>>
Curry<T1, T2, TResult>(this Func<T1, T2, TResult> func)
{
Func<Func<T1, T2, TResult>, Func<T1, Func<T2, TResult>>> curried
= f => x => y => f(x, y);
return curried(func);
}
}
This is quite verbose, requires explicit definition of the parameters and return type of the string.Join overload I want to use, and relies upon C#4's variance features because we are defining one of the arguments as IEnumerable rather than IEnumerable.
The Challenge
Can you find a neater way of achieving this using the method-chaining style of programming?
© Stack Overflow or respective owner