June 01, 2012
Но тогда почему при замене 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();
}
June 01, 2012
On 01.06.2012 15:16, Zhenya wrote:
> Но тогда почему при замене 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);

Может все-таки
Bind!([1,0,3], &checker!(int, int, int, int), 2, 1, 4)(3)

т.е. изначально имелось в виду
Bind!([1,0,3]).bind!(&checker!(int,int,int,int),2,1,4)(3) ?

тогда должно работать.

Иными словами не более одного списка !(...). Компилятор не ошибется выбирая из него аргументы слева направо по мере необходимости.

> readln();
> }


-- 
Dmitry Olshansky
June 01, 2012
On Friday, 1 June 2012 at 11:23:48 UTC, Dmitry Olshansky wrote:
> On 01.06.2012 15:16, Zhenya wrote:
>> Но тогда почему при замене 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);
>
> Может все-таки
> Bind!([1,0,3], &checker!(int, int, int, int), 2, 1, 4)(3)
>
> т.е. изначально имелось в виду
> Bind!([1,0,3]).bind!(&checker!(int,int,int,int),2,1,4)(3) ?
>
> тогда должно работать.
>
> Иными словами не более одного списка !(...). Компилятор не ошибется выбирая из него аргументы слева направо по мере необходимости.
>
>> readln();
>> }
В том-то и дело,что (&checker!(int,int,int,int),2,1,4) - аргументы времени выполнения.Значит: bind!([1,0,3])(&checker!(int,int,int,int),2,1,4)(3)
но не хочет компилится(

June 01, 2012
On 01.06.2012 15:40, Zhenya wrote:
> On Friday, 1 June 2012 at 11:23:48 UTC, Dmitry Olshansky wrote:
>> On 01.06.2012 15:16, Zhenya wrote:
>>> Но тогда почему при замене 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);
>>
>> Может все-таки
>> Bind!([1,0,3], &checker!(int, int, int, int), 2, 1, 4)(3)
>>
>> т.е. изначально имелось в виду
>> Bind!([1,0,3]).bind!(&checker!(int,int,int,int),2,1,4)(3) ?
>>
>> тогда должно работать.
>>
>> Иными словами не более одного списка !(...). Компилятор не ошибется
>> выбирая из него аргументы слева направо по мере необходимости.
>>
>>> readln();
>>> }
> В том-то и дело,что (&checker!(int,int,int,int),2,1,4) - аргументы
> времени выполнения.Значит:
> bind!([1,0,3])(&checker!(int,int,int,int),2,1,4)(3)
> но не хочет компилится(
>

Лог ошибок в студию.

-- 
Dmitry Olshansky
June 01, 2012
Error	3	Error: function expected before (), not bind(&checker,2,1,4) of type _error_	c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d	98	

Error	1	Error: template instance bind!([0,2]) bind!([0,2]) does not match template declaration bind(D,V...)	c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d	81	

Error	2	Error: template instance main.bind!([1,0,3]).bind!(void delegate(int _param_0, int _param_1, int _param_2, int _param_3) @system,int,int,int) error instantiating	c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d	98	


June 01, 2012
On 01.06.2012 15:47, Zhenya wrote:
> Error 3 Error: function expected before (), not bind(&checker,2,1,4) of
> type _error_ c:\users\zhenya\documents\visual studio
> 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98
>
> Error 1 Error: template instance bind!([0,2]) bind!([0,2]) does not
> match template declaration bind(D,V...) c:\users\zhenya\documents\visual
> studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 81
>
> Error 2 Error: template instance main.bind!([1,0,3]).bind!(void
> delegate(int _param_0, int _param_1, int _param_2, int _param_3)
> @system,int,int,int) error instantiating
> c:\users\zhenya\documents\visual studio
> 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98
>
>

It may have some problem with matching this delegate hmmm.
What if you try this:

template Bind(alias indeces)
	if(is(typeof(indeces) : int[]))
{
	auto bind(V...)(alias dg,V values)	
		if(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
			assert(0);
	}
}
alias instead of delegate - it's just more powerful
I relaxed constraints and static ifs ---> proper template constraints.

-- 
Dmitry Olshansky
June 01, 2012
On Friday, 1 June 2012 at 12:38:11 UTC, Dmitry Olshansky wrote:
> On 01.06.2012 15:47, Zhenya wrote:
>> Error 3 Error: function expected before (), not bind(&checker,2,1,4) of
>> type _error_ c:\users\zhenya\documents\visual studio
>> 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98
>>
>> Error 1 Error: template instance bind!([0,2]) bind!([0,2]) does not
>> match template declaration bind(D,V...) c:\users\zhenya\documents\visual
>> studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 81
>>
>> Error 2 Error: template instance main.bind!([1,0,3]).bind!(void
>> delegate(int _param_0, int _param_1, int _param_2, int _param_3)
>> @system,int,int,int) error instantiating
>> c:\users\zhenya\documents\visual studio
>> 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98
>>
>>
>
> It may have some problem with matching this delegate hmmm.
> What if you try this:
>
> template Bind(alias indeces)
> 	if(is(typeof(indeces) : int[]))
> {
> 	auto bind(V...)(alias dg,V values)	
> 		if(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
> 			assert(0);
> 	}
> }
> alias instead of delegate - it's just more powerful
> I relaxed constraints and static ifs ---> proper template constraints.
Error	1	basic type expected, not alias	c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d	75	
Похоже что alias не может быть аргументом времени выполнения


June 01, 2012
Да,на всякий случай,текущий исходник,который не компилится

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])(&checker!(int,int,int,int),2,1,4)(3);
	readln();
}
June 01, 2012
On 01.06.2012 16:47, Zhenya wrote:
> On Friday, 1 June 2012 at 12:38:11 UTC, Dmitry Olshansky wrote:
>> On 01.06.2012 15:47, Zhenya wrote:
>>> Error 3 Error: function expected before (), not bind(&checker,2,1,4) of
>>> type _error_ c:\users\zhenya\documents\visual studio
>>> 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98
>>>
>>> Error 1 Error: template instance bind!([0,2]) bind!([0,2]) does not
>>> match template declaration bind(D,V...) c:\users\zhenya\documents\visual
>>> studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 81
>>>
>>> Error 2 Error: template instance main.bind!([1,0,3]).bind!(void
>>> delegate(int _param_0, int _param_1, int _param_2, int _param_3)
>>> @system,int,int,int) error instantiating
>>> c:\users\zhenya\documents\visual studio
>>> 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 98
>>>
>>>
>>
>> It may have some problem with matching this delegate hmmm.
>> What if you try this:
>>
>> template Bind(alias indeces)
>> if(is(typeof(indeces) : int[]))
>> {
>> auto bind(alias dg, V...)(V values)
>> if(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
>> assert(0);
>> }
>> }
>> alias instead of delegate - it's just more powerful
>> I relaxed constraints and static ifs ---> proper template constraints.
> Error 1 basic type expected, not alias c:\users\zhenya\documents\visual
> studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 75
> Похоже что alias не может быть аргументом времени выполнения
>
>

ну как же map, filter и тд работают )
ну передавай свой delegate как параметр времени компиляции через !(...)
все будет ок ...

auto bind(alias dg, V...)(V values)
>> if(is(V == Combination!(indeces,ParameterTypeTuple!D)))
>> {
>> static if(indeces.length > 1)
>> return

 Bind!(update!(indeces,indeces[0])[1..$]).bind!(Curry! (indeces[0])
 (values[0]),values[1..$]);

>> else
>> assert(0);
>> }
>> }

-- 
Dmitry Olshansky
June 01, 2012
> ну как же map, filter и тд работают )
> ну передавай свой delegate как параметр времени компиляции через !(...)
> все будет ок ...
нууу так не прикольно.
А это часом не бага у DMD?