Quantcast
Channel: Programming – Mr Pfisters Random Waffle
Viewing all articles
Browse latest Browse all 15

Currying Function C#

$
0
0

A while ago I did a post about Lambda calculus in C#, mainly focusing on how you can implement the concept of Y combinators. Y combinators are one of the simplest fixed point combinators in Lambda calculus, and was discovered by a Mr Curry. One of the other interesting concepts of Lambda calculus is the concept of ‘Currying’.

Heres a quick foray back at Y Combinator:

///
/// One-argument Y-Combinator.
///
public static Func<T, TResult> Y<T, TResult>(Func<Func<T, TResult>, Func<T, TResult>> F)
{
	return t => F(Y(F))(t);
}

///
/// Two-argument Y-Combinator.
///
public static Func<T1, T2, TResult> Y<T1, T2, TResult>(Func<Func<T1, T2, TResult>, Func<T1, T2, TResult>> F)
{
	return (t1, t2) => F(Y(F))(t1, t2);
}

///
/// Three-arugument Y-Combinator.
///
public static Func<T1, T2, T3, TResult> Y<T1, T2, T3, TResult>(Func<Func<T1, T2, T3, TResult>, Func<T1, T2, T3, TResult>> F)
{
	return (t1, t2, t3) => F(Y(F))(t1, t2, t3);
}

///
/// Four-arugument Y-Combinator.
///
public static Func<T1, T2, T3, T4, TResult> Y<T1, T2, T3, T4, TResult>(Func<Func<T1, T2, T3, T4, TResult>, Func<T1, T2, T3, T4, TResult>> F)
{
	return (t1, t2, t3, t4) => F(Y(F))(t1, t2, t3, t4);
}

Currying is the concept of integrating an argument of a function into a new function with the argument built in.

Take the following maths equation:

f(a, b, c) where f = a + b + c

so

f(1, 2, 3) would mean f = 6

The concept of currying takes the argument and effectively hardcoding it, so take a look again at the previous function.

Currying f(1, b, c) would produce a new function f1(b, c) where f1 = 1 + b + c

This idea is important of things like constructors or overloading functions, where some arguments may be fixed.

Currying in C# lambda calculus looks like the following:

// Curry first argument
public static Func<T1, Func<T2, TResult>> Curry<T1, T2, TResult>(Func<T1, T2, TResult> F)
{
	return t1 => t2 => F(t1, t2);
}

// Curry second argument.
public static Func<T2, Func<T1, TResult>> Curry2nd<T1, T2, TResult>(Func<T1, T2, TResult> F)
{
	return t2 => t1 => F(t1, t2);
}

// Uncurry first argument.
public static Func<T1, T2, TResult> Uncurry<T1, T2, TResult>(Func<T1, Func<T2, TResult>> F)
{
	return (t1, t2) => F(t1)(t2);
}

// Uncurry second argument.
public static Func<T1, T2, TResult> Uncurry2nd<T1, T2, TResult>(Func<T2, Func<T1, TResult>> F)
{
	return (t1, t2) => F(t2)(t1);
}

Viewing all articles
Browse latest Browse all 15

Trending Articles