Но тогда почему при замене Bind -> bind
вот этот код не компилируется?
module main;

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

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) : int[]))
        {
                static if(indeces.length > 1)
alias TypeTuple!(U[indeces[0]],Combination!(indeces[1..$],U)) Combination;
                else static if(indeces.length == 1)
                        alias TypeTuple!(U[indeces[0]]) Combination;
        }
}

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

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

void main()
{
        void checker(T...)(T args)
        {
                foreach(i,current;args)
                {
                        writeln("x",i," = ",current);
                }
        }
        Bind!([1,0,3]).bind(&checker!(int,int,int,int),2,1,4)(3);
        readln();
}

Reply via email to