D中用于currying函数的模板?

问题描述 投票:0回答:1

是否有可能编写可用于自动管理D中函数的模板或类似文件?手动写出所有嵌套的委托人会杀死我。

基本上,对于具有[ 3个参数,通常可以像f一样调用,我希望它可以像f(a,b,c)那样调用。

我知道f(a)(b)(c),但这不是我想要的。我想翻译函数定义端,而不是调用端。

我也知道这不是最佳实践,但是我正在生成代码,所以请多多包涵。

templates d
1个回答
0
投票

嗯,遵循这些原则应该可以完成这项工作:

std.functional.partial

这个想法很简单:根据剩余的参数生成辅助函数-如果有的话,返回该辅助对象的地址作为委托,否则,只需返回调用收集的参数的委托即可。一点递归处理1+ arg情况,而静态if则通过返回原始函数处理0 arg情况。

要注意的语言功能:

  • 同名模板。如果模板的成员与模板具有相同的名称(在本例中为autocurry),则在使用时会自动对其进行引用。

  • 元组扩展。当我调用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("called test"); return "no args"; } 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()); } 时,作为内置元组的what(arg, args)将自动展开以创建完整的参数列表。

  • 此处各种自动返回(显式args和隐式auto autocurry关键字,未指定返回类型)仅转发主体碰巧返回的任何其他随机类型。

  • 在主函数中,我执行了delegate(我经常使用lol作为占位符名称,哈哈)。您也可以在顶级对其进行重载:

alias lol = autocurry!foo;

现在您可以直接在原件旁边使用它:

      int foo(int a, string b, float c) {
              import std.stdio; writeln(a, " ", b, " ", c);
              return 42;
      }

      alias foo = autocurry!foo; // overloads the auto-curried foo with the original foo

如果您希望使用新名称,或者过载由您自己决定,则两者都可以使用。

请注意,每个参数都有可能分配一些内存来存储给下一个委托。 GC将负责清理。

© www.soinside.com 2019 - 2024. All rights reserved.