Problem with closures: Problem solved

Bradley Smith digitalmars-com at baysmith.com
Thu Jan 11 16:20:01 PST 2007


Applying the Curry method to the current example yields the following.

import std.stdio;

alias int delegate(int x) AddFunc;

AddFunc addN(int n) {
     int add(int a, int b) {
         return a + b;
     }
     return Curry(&add, n); // the add function captured will remember the value of n
}

void apply(int[] array, AddFunc func) {
     foreach (inout int i; array) {
         i = func(i);
     }
}

int main() {
     int[] numbers = [1,2,3];
     writefln("numbers before=",numbers);
     apply(numbers, addN(40)); // add 40 to each number
     writefln("numbers after=",numbers);

     return 0;
}

/* R is return type
  * A is first argument type
  * U is TypeTuple of rest of argument types
  */
R delegate(U) Curry(R, A, U...)(R delegate(A, U) dg, A arg) {
     struct Closure {
         typeof(dg) originalDelegate;
         A value;

         R subDelegate(U u) {
             return originalDelegate(value, u);
         }
     }

     Closure* f = new Closure;
     f.originalDelegate = dg;
     f.value = arg;
     return &f.subDelegate;
}


Daniel Giddings wrote:
> There is also a templated Curry function example in the D template docs:
> 
> http://www.digitalmars.com/d/template.html
> 
> /* R is return type
>  * A is first argument type
>  * U is TypeTuple of rest of argument types
>  */
> 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 u)
>     {
>         return dg_m(arg_m, u);
>     }
>     }
> 
>     Foo* f = new Foo;
>     f.dg_m = dg;
>     f.arg_m = arg;
>     return &f.bar;
> }
> 
> void main()
> {
>     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));    // prints 16
> }


More information about the Digitalmars-d-learn mailing list