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: 429

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

Related posts about c#

Related posts about functional-programming