A functor-based curry
downs
default_357-line at yahoo.de
Tue Jan 29 06:20:07 PST 2008
[snip]
Your example doesn't work because a function template must only contain exactly a single defined symbol that has the same name as the template.
Here's a simple functor version:
> import std.stdio, std.traits;
>
A sample function
> int add(int a, int b, int c) { return a+b+c; }
>
The initialization of T
> template Init(T) { T Init; }
>
> class CurryFunctor(C, P...) {
> C callable;
> P params;
> this(C c, P p) {
> callable = c;
> foreach (id, v; p) params[id] = v;
> }
The purpose of this is to allow a kind of automatic return type deduction.
Think of this as the function body of opCall.
> const string CODE = "
> static if (is(typeof(callable(params, Init!(R))))) {
> return callable(params, rest);
> } else
> return curry(callable, params, rest);
> ";
Now we use our function body to determine the return type of opCall, by asking the question:
"If our function were a function literal that took no parameters (declaring rest as a variable;
this is okay because this function literal is never called), then what would its type be?"
> typeof(mixin("function(){ R rest; "~CODE~" }()")) opCall(R...)(R rest) {
> mixin(CODE);
> }
> }
>
A simple wrapper.
> CurryFunctor!(C, P) curry(C, P...)(C callable, P params) {
> return new CurryFunctor!(C, P)(callable, params);
> }
>
And examples.
> void main() {
> writefln(curry(&add, 2, 3)(5));
> writefln(curry(&add, 2)(3)(4));
> }
Have fun with it!
--downs
More information about the Digitalmars-d-learn
mailing list