Problem with closures: Problem solved

Daniel Giddings dgiddings at bigworldtech.com
Thu Jan 11 18:08:02 PST 2007


Or with a small modification to Curry to curry a function instead of a 
delegate:

import std.stdio;

alias int delegate(int x) AddFunc;

int add(int a, int b) {
	return a + b;
}

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, CurryFunc( &add, 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) CurryFunc(R, A, U...)(R function(A, U) fn, A arg) {
     struct Closure {
         typeof(fn) originalFunction;
         typeof(A) value;

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

     Closure* f = new Closure;
     f.originalFunction = fn;
     f.value = arg;
     return &f.subDelegate;
}

Bradley Smith wrote:
> 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;
> }
> 
> 


More information about the Digitalmars-d-learn mailing list