Re: Ой, чо с D деется-то!?
От: Андрей Хропов Россия  
Дата: 16.11.06 23:20
Оценка: 41 (3)
Здравствуйте, 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>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.