Здравствуйте, eao197, Вы писали:
E>А вот пример из описания туплов D:
R delegate() CurryAll(Dummy=void, R, U...)(R function(U) dg, U args)
{
struct Foo
{
typeof(dg) dg_m;
U args_m;
R bar()
{
return dg_m(args_m);
}
}
Foo* f = new Foo;
f.dg_m = dg;
foreach (i, arg; args)
f.args_m[i] = arg;
return &f.bar;
}
R delegate() CurryAll(R, U...)(R delegate(U) dg, U args)
{
struct Foo
{
typeof(dg) dg_m;
U args_m;
R bar()
{
return dg_m(args_m);
}
}
Foo* f = new Foo;
f.dg_m = dg;
foreach (i, arg; args)
f.args_m[i] = arg;
return &f.bar;
}
void main()
{
static int plus(int x, int y, int z)
{
return x + y + z;
}
auto plus_two = CurryAll(&plus, 2, 3, 4);
printf("%d\n", plus_two());
assert(plus_two() == 9);
int minus(int x, int y, int z)
{
return x + y + z;
}
auto minus_two = CurryAll(&minus, 7, 8, 9);
printf("%d\n", minus_two());
assert(minus_two() == 24);
}
Для того чтобы почувствовать разницу вот тот же самый код на Nemerle
(тут также пример и с полной (что фактически эквивалентно ленивому исполнению) и частичной currying,
то что у Вальтера называется Curry и CurryAll (
здесь) ):
using Nemerle;
using System.Console;
def plus(x,y,z){ x+y+z }
def minus(x,y,z){ x-y-z }
def plus_two = plus(2,_,_);
WriteLine($"$(plus_two(6, 8))");
def plus_three = plus_two(3,_);
WriteLine($"$(plus_three(7))");
def plus_all = lazy( plus(7,8,9) );
WriteLine($"$plus_all");
def minus_all = lazy( minus(7,8,9) );
WriteLine($"$minus_all");
Да, а вот
здесьнекто Reiner Pope соорудил шаблон RealCurry, который делает из функций
типа plus(1,2,3) функции типа curried_plus(1)(2)(3):
void main()
{
static int plus(int x, int y, int z)
{
return x + y + z;
}
auto curried_plus = RealCurry(&plus);
auto plus_two = curried_plus(2);
auto plus_two_plus_three = plus_two(3);
writefln(plus_two_plus_three(4)); // 9
writefln(plus_two(5)(6)); // 13
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>