Function Currying

Walter Bright newshound at digitalmars.com
Tue Nov 14 17:58:07 PST 2006


D's tuple support has reached the point where function currying is 
straightforward. I held off from doing a standard library with these 
because Tom S's bind library is much more comprehensive, and I hope 
he'll update it with these.

------ Curry first argument -----------------

R delegate(U) Curry(Dummy=void, R, A, U...)(R function(A, U) dg, A arg)
{
     struct Foo
     {
	typeof(dg) dg_m;
	typeof(arg) arg_m;

	R bar(U r)
	{
	    return dg_m(arg_m, r);
	}
     }

     Foo* f = new Foo;
     f.dg_m = dg;
     f.arg_m = arg;
     return &f.bar;
}

R delegate(U) Curry(R, A, U...)(R delegate(A, U) dg, A arg)
{
     struct Foo
     {
	typeof(dg) dg_m;
	typeof(arg) arg_m;

	R bar(U r)
	{
	    return dg_m(arg_m, r);
	}
     }

     Foo* f = new Foo;
     f.dg_m = dg;
     f.arg_m = arg;
     return &f.bar;
}

void main()
{
     static int plus(int x, int y, int z)
     {
	return x + y + z;
     }

     auto plus_two = Curry(&plus, 2);
     printf("%d\n", plus_two(6, 8));
     auto plus_three = Curry(plus_two, 3);
     printf("%d\n", plus_three(7));

     int minus(int x, int y, int z)
     {
	return x + y + z;
     }

     auto minus_two = Curry(&minus, 2);
     printf("%d\n", minus_two(6, 8));
     auto minus_three = Curry(minus_two, 3);
     printf("%d\n", minus_three(7));
}
-------- Curry all the arguments -------------------------

R delegate() CurryAll(Dummy=void, R, U...)(R function(U) dg, U args)
{
     struct Foo
     {
	typeof(dg) dg_m;
	U args_m;

	R bar()
	{
	    return dg_m(args_m);
	}
     }

     Foo* f = new Foo;
     f.dg_m = dg;
     foreach (i, arg; args)
	f.args_m[i] = arg;
     return &f.bar;
}

R delegate() CurryAll(R, U...)(R delegate(U) dg, U args)
{
     struct Foo
     {
	typeof(dg) dg_m;
	U args_m;

	R bar()
	{
	    return dg_m(args_m);
	}
     }

     Foo* f = new Foo;
     f.dg_m = dg;
     foreach (i, arg; args)
	f.args_m[i] = arg;
     return &f.bar;
}


void main()
{
     static int plus(int x, int y, int z)
     {
	return x + y + z;
     }

     auto plus_two = CurryAll(&plus, 2, 3, 4);
     printf("%d\n", plus_two());
     assert(plus_two() == 9);

     int minus(int x, int y, int z)
     {
	return x + y + z;
     }

     auto minus_two = CurryAll(&minus, 7, 8, 9);
     printf("%d\n", minus_two());
     assert(minus_two() == 24);
}
-----------------------



More information about the Digitalmars-d mailing list