Skip to content

Instantly share code, notes, and snippets.

@JakobOvrum
Created October 17, 2015 16:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakobOvrum/1a19f670e7a3359006af to your computer and use it in GitHub Desktop.
Save JakobOvrum/1a19f670e7a3359006af to your computer and use it in GitHub Desktop.
Curry implementation using delegates (inefficient but yields known types)
import std.traits : isCallable;
private auto curryImpl(F, CurriedArgs...)(F f, CurriedArgs curriedArgs)
{
import std.traits : ParameterTypeTuple;
alias Args = ParameterTypeTuple!F;
static if(CurriedArgs.length == Args.length - 1)
return (Args[CurriedArgs.length] lastArg) => f(curriedArgs, lastArg);
else
return (Args[CurriedArgs.length] nextArg) => curryImpl(f, curriedArgs, nextArg);
}
auto curry(F)(F f)
if(isCallable!F)
{
import std.traits : ParameterTypeTuple;
alias Args = ParameterTypeTuple!F;
static if(Args.length <= 1)
return f;
else
return (Args[0] arg) => curryImpl(f, arg);
}
unittest
{
int delegate() nullary = () { return 42; };
assert(curry(nullary)() == 42);
int delegate(int) unary = a => a;
assert(curry(unary)(42) == 42);
int delegate(int, int, int) sum = (a, b, c) => a + b + c;
static assert(is(typeof(curry(sum)) == int delegate(int) delegate(int) pure nothrow @safe delegate(int) pure nothrow @safe));
assert(curry(sum)(1)(2)(3) == 6);
string delegate(string, int) concat = (str, n) {
string result;
foreach(immutable i; 0 .. n)
result ~= str;
return result;
};
assert(curry(concat)("foo")(3) == "foofoofoo");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment