d的自动柯里化
自动柯里化
f(a,b,c)按f(a)(b)(c)调用.
template autocurry(alias what) {
import std.traits;
static if(Parameters!what.length)
auto autocurry(Parameters!what[0] arg) {
alias Remainder = Parameters!what[1 .. $];
auto dg = delegate(Remainder args) {
return what(arg, args);
};
static if(Remainder.length > 1)
return &autocurry!dg;
else
return dg;
}
else
alias autocurry = what;
}
int foo(int a, string b, float c) {
import std.stdio; writeln(a, " ", b, " ", c);
return 42;
}
string test() {
import std.stdio; writeln("调用测试");
return "无参";
}
void main() {
import std.stdio;
alias lol = autocurry!foo;
writeln(lol(30)("lol")(5.3));
auto partial = lol(20);
partial("wtf")(10.5);
alias t = autocurry!test;
writeln(t());
}
想法很简单:如果有,根据剩余参数生成辅助函数,按闭包返回辅助函数地址,否则,只返回调用收集参数的闭包.递归处理多参,而外部静如仅返回原始函数来处理无参.
需要注意的语言特征:
1,同名模板.模板具有与模板同名的成员时(在本例中为autocurry),使用时会自动引用它.
2,扩展元组.调用(arg,args)时,内置元组的args会自动扩展来创建完整参数列表.
3,各种自动返回(不指定返回类型的显式auto autocurry和隐式delegate关键字),只是转发返回的其他随机类型.
4,main函数中,
alias lol = autocurry!foo;
//lol为占位符,
示例.
int foo(int a, string b, float c) {
import std.stdio;
writeln(a, " ", b, " ", c);
return 42;
}
alias foo = autocurry!foo;
//用原foo重载自动柯里foo
//使用
void main() {
foo(30)("lol")(5.3); // 柯里版
foo(40, "cool", 103.4); // 原版
}
浙公网安备 33010602011771号