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); // 原版
}
posted @   zjh6  阅读(21)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示