Spice Up Your C# Code With Currying

[UPDATE: When I first posted this, I used the term currying  to describe partial function application. Though they are related concepts, they mean different things. Since this post is more about partial function application than currying, I have corrected the terminology below.]

C# doesn’t have language supp1ort for currying, but that doesn’t mean that you can’t spice up your code by currying or partially applying methods yourself. It’s also very easy to do:

public static Func<T2, TR> Bind1<T1, T2, TR>(Func<T1, T2, T3> function, T1 param1)
{
   return delegate(T2 param2) { return function(param1, param2); };
}

As you can see, this simple method returns a delegate accepting one parameter corresponding to the second argument of the input function. This means that the returned delegate acts the same way as the input function, except that the first argument is now bound to the input parameter. We’ve partially applied the method.

Let’s see an example of this in practice:

private static string CreateMessage(string a, string b)
{
   return string.Format("Let's write a message.... {0} + {1}", a, b);
} 
static void Main(string[] args)
{
   Func<string, string, string> tmp = CreateMessage;
   var paritallyAppliedCreate = Bind1(tmp, "Some crazy string value");

   Console.WriteLine(paritallyAppliedCreate("Another insane string"));
   Console.WriteLine(paritallyAppliedCreate("and another"));
   Console.WriteLine(paritallyAppliedCreate("yet another"));
}

The output:

Let’s write a message…. Some crazy string value + Another insane string!

Let’s write a message…. Some crazy string value + and another

Let’s write a message…. Some crazy string value + yet another

Pretty cool. Now, there is a little bit of work to do because you have to write a new bind function for each number of arguments that you want to support. I supported up to 4 arguments, since that meshes with the definition of Func. You also will probably want to write out Bind1, Bind2, Bind3, and Bind4 methods, so that you aren’t limited to always binding to the first argument. That’s a lot of "duplicated" code for the definitions, but C# doesn’t have a way to specify variable-arity (think params[]) for generic parameters, so you’re stuck writing everything out.

[UPDATE: instead of writing these bind methods by hand, you can use Elevate or just use F#]

Another interesting thing to note is that you have to explicitly cast your method as a Func for this to work, or you’ll get a "type arguments cannot be inferred from usage" compile error. It would be nice to be able to just write:

var CurriedCreate = Bind1(CreateMessage); 

but, alas, C#’s type inference doesn’t let you do this. Implementing Bind1 as an extension method is one option to clean up the syntax, though:

public static Func<T2, TR> Bind1<T1, T2, TR>(this Func<T1, T2, TR> function, T1 param1)
{
   return delegate(T2 param2) { return function(param1, param2); };
} 

private static string CreateMessage(string a, string b)
{
   return string.Format("Let's write a message.... {0} + {1}", a, b);
} 

static void Main(string[] args)
{
   Func<string , string, string> tmp = CreateMessage;
   var paritallyAppliedCreate = tmp.Bind1("Some crazy string value");

   Console.WriteLine(paritallyAppliedCreate("Another insane string!"));
   Console.WriteLine(paritallyAppliedCreate("and another"));
   Console.WriteLine(paritallyAppliedCreate("yet another"));
}

Note that there is a lot more to say on this subject, but that will have to wait for another post.

This entry was posted in C#, Functional. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Post a Comment

Your email is never published nor shared. Required fields are marked *

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*
*