Skip to content

Instantly share code, notes, and snippets.

@esnya
Created March 20, 2015 14:42
Show Gist options
  • Save esnya/fc89e06937f4ac6b2d73 to your computer and use it in GitHub Desktop.
Save esnya/fc89e06937f4ac6b2d73 to your computer and use it in GitHub Desktop.
カリー化してみる
import std.traits;
import std.typecons;
private struct Curry(alias Func, size_t Index = 0) {
private alias _Types = ParameterTypeTuple!Func;
private Tuple!(_Types[0 .. Index]) _args;
static if (Index + 1 == _Types.length) {
ReturnType!Func opCall(_Types[Index] arg) {
return Func(_args.expand, arg);
}
} else {
auto opCall(_Types[Index] arg) {
Curry!(Func, Index + 1) curry;
curry._args = tuple(_args.expand, arg);
return curry;
}
}
}
auto curry(alias Func)() {
Curry!(Func, 0) curry;
return curry;
}
auto curry(alias Func, T)(T arg) {
return curry!Func()(arg);
}
unittest {
import std.stdio;
int f(int x, int y, int z) {
return x * y * z;
}
writeln(curry!f);
writeln(curry!f(2));
writeln(curry!f(2)(3));
writeln(curry!f(2)(3)(4));
assert(f(2, 3, 4) == curry!f(2)(3)(4));
auto a = curry!f;
assert(f(2, 3, 4) == a(2)(3)(4));
auto b = a(3);
assert(f(3, 4, 5) == b(4)(5));
auto c = a(4);
assert(f(4, 5, 6) == c(5)(6));
enum A = curry!f;
static assert(f(1, 2, 3) == A(1)(2)(3));
enum B = curry!f(1);
static assert(f(1, 2, 3) == B(2)(3));
enum C = curry!f(1)(2);
static assert(f(1, 2, 3) == C(3));
enum D = curry!f(1)(2)(3);
static assert(f(1, 2, 3) == D);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment