import std.stdio;
import std.typecons;
import std.typetuple;

template Erase(int k,TList...)
{
        static if(k != 0)
                alias TypeTuple!(TList[0],Erase!(k-1,TList[1..$])) Erase;
        else
                alias TList[1..$] Erase;
}

auto Curry(uint i,R,T,U...)(R delegate(U) dg, T arg)
{
        struct Foo
        {
                typeof(dg) m_dg;
                T m_arg;
                R bar(Erase!(i,U) args)
                {
                        U m_args;
                        static if(i > 0)
                                m_args[0..i] = args[0..i];
                        m_args[i] = m_arg;
                        static if(i < args.length)
                                m_args[i+1..$] = args[i..$];
                        return m_dg(m_args);
                }
        }
        Foo* f = new Foo;
        f.m_dg = dg;
        f.m_arg  = arg;
        return &f.bar;
}

template Combination(alias indeces,U...)
{
//      static if(is(typeof(indeces) : uint[]))
//      {
                static if(indeces.length > 1)
alias TypeTuple!(U[indeces[0]],Combination!(indeces[1..$],U)) Combination;
                else static if(indeces.length == 1)
                        alias U[indeces[0]] Combination;
//      }
}

template update(alias indeces,int current)
{
//      static if(is(typeof(indeces) : uint[]))
//      {
                static if(indeces.length > 1)
                {
                        static if(indeces[0] > current)
enum uint[] update = (indeces[0]-1)~update!(indeces[1..$],current);
                        else
enum uint[] update = indeces[0]~update!(indeces[1..$],current);
                }
                else static if(indeces.length == 1)
                {
                        static if(indeces[0] > current)
                                enum uint[] update = [indeces[0]-1];
                        else
                                alias indeces update;
                }
//      }
}

template bind(alias indeces)
{
//      static if(is(typeof(indeces) : uint[]))
//      {
auto bind(R,U...)(R delegate(U) dg,Combination!(indeces,U) values)
                {
                        static if(indeces.length > 1)
return bind!(update!(indeces,indeces[0]))(Curry!(indeces[0])(dg,values[0]),values[1..$]);
                        else static if(indeces.length == 1)
                                return Curry!(indeces[0])(dg,values[0]);
                }
//      }
}

void main()
{
        void xyz(int x,int y,int z)
        {
                writeln("x = ",x," y = ",y," z = ",z);
        }
        auto g = Curry!1(&xyz,cast(int)(1.1));
        g(2,3);
        alias Combination!([0,1],int,int,int) Arg;
        Arg a;
        auto h = 0;bind!([0,1])(&xyz,a);
        readln();
}

C:\Users\Zhenya\Desktop\second.d(92): Error: template second.bind!([0,1]).bind does not match any function template declaration C:\Users\Zhenya\Desktop\second.d(72): Error: template second.bind!([0,1]).bind(R,U...) cannot deduce template function from argument types !()(void delegate(int x, int y, int z),int,int)

Reply via email to