Function Currying

David Medlock noone at nowhere.com
Wed Nov 15 06:11:49 PST 2006


David Medlock wrote:

> Walter Bright wrote:
> 
>> 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);
>> }
>> -----------------------
> 
> 
> Nice walter.
> 
> Its too bad though that inner function delegates don't live past the 
> stack frame or this wouldn't really be necessary..hehe.
> 
> -DavidM

Oh yes I will add another plug for a great book which explains currying 
in the context of functions as well as programs:

http://www.dina.dk/~sestoft/pebook/

-DavidM




More information about the Digitalmars-d mailing list