digitalmars.D.learn - problem with template arguments deduction
- Zhenya (43/43) May 30 2012 Some time ago I decided to write in D something like boost ::
- Philippe Sigaud (49/49) May 30 2012 I don't see anything wrong per se. It's mainly that the compiler type
- Zhenya (2/55) May 30 2012 Thank you very much:)
- Zhenya (12/12) May 30 2012 And, one more thing
- Philippe Sigaud (2/14) May 31 2012 I'm not sure I understand the question?
- Dmitry Olshansky (6/18) May 31 2012 If you happen to be Russian, feel free to include Russian as well. I
- Zhenya (19/19) Jun 01 2012 Вот у нас есть такая конструкция
- Zhenya (19/19) Jun 01 2012 Вот у нас есть такая конструкция
- Zhenya (1/1) Jun 01 2012 Простите меня за мой английский)
- Dmitry Olshansky (25/51) Jun 01 2012 In other words:
- Zhenya (98/98) Jun 01 2012 Но тогда почему при замене Bind -> bind
- Dmitry Olshansky (10/106) Jun 01 2012 Может все-таки
- Zhenya (6/122) Jun 01 2012 В том-то и дело,что
- Dmitry Olshansky (4/128) Jun 01 2012 Лог ошибок в студию.
- Zhenya (13/13) Jun 01 2012 Error 3 Error: function expected before (), not
- Dmitry Olshansky (21/32) Jun 01 2012 It may have some problem with matching this delegate hmmm.
- Zhenya (6/45) Jun 01 2012 Error 1 basic type expected, not
- Dmitry Olshansky (9/57) Jun 01 2012 ну как же map, filter и тд работают )
- Zhenya (2/7) Jun 01 2012 нууу так не прикольно.
- Dmitry Olshansky (7/12) Jun 01 2012 Ну их много, заполни репорт в
- Zhenya (40/47) Jun 01 2012 кстати если я заменяю
- Zhenya (2/2) Jun 02 2012 Дмитрий,не подскажите как я бы мог
- Dmitry Olshansky (42/43) Jun 02 2012 Как я и говорил отписать что это баг. Да...
- Zhenya (1/1) Jun 02 2012 Куда отписать-то?)
- Dmitry Olshansky (4/5) Jun 02 2012 http://d.puremagic.com/issues/
- Zhenya (98/98) Jun 01 2012 Да,на всякий случай,текущий
Some time ago I decided to write in D something like boost ::
bind.But I encountered a problem that the compiler can not deduce
the template function. Here are a significant part of the code:
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 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;
bind!([0,1])(&xyz,a);
readln();
}
Please, explain to me what is wrong with this code
May 30 2012
I don't see anything wrong per se. It's mainly that the compiler type
extraction/deduction is not powerful enough to extract U in your case.
You can help it a bit by using std.traits.ParameterTypeTuple:
module test;
import std.stdio;
import std.traits;
import std.typetuple;
template Combination(alias indices,U...)
{
static if(is(typeof(indices) : int[]))
{
static if(indices.length > 1)
alias
TypeTuple!(U[indices[0]],Combination!(indices[1..$],U)) Combination;
else static if(indices.length == 1)
alias U[indices[0]] Combination;
}
}
template bind(alias indices)
{
static if(is(typeof(indices) : int[]))
{
auto bind(D,V...)(D dg, V values) if (is (D d == R
delegate(U), R, U...) && is(V == Combination!(indices,
ParameterTypeTuple!D)))
{
/* static if(indices.length > 1)
return
bind!(update!(indices,indices[0]))(Curry!(indices[0])(dg,values[0]),values[1..$]);
else static if(indices.length == 1)
return Curry!(indices[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;
writeln(Arg.stringof);
bind!([0,1])(&xyz,a);
//readln();
}
May 30 2012
On Wednesday, 30 May 2012 at 22:19:53 UTC, Philippe Sigaud wrote:
I don't see anything wrong per se. It's mainly that the
compiler type
extraction/deduction is not powerful enough to extract U in
your case.
You can help it a bit by using std.traits.ParameterTypeTuple:
module test;
import std.stdio;
import std.traits;
import std.typetuple;
template Combination(alias indices,U...)
{
static if(is(typeof(indices) : int[]))
{
static if(indices.length > 1)
alias
TypeTuple!(U[indices[0]],Combination!(indices[1..$],U))
Combination;
else static if(indices.length == 1)
alias U[indices[0]] Combination;
}
}
template bind(alias indices)
{
static if(is(typeof(indices) : int[]))
{
auto bind(D,V...)(D dg, V values) if (is (D d == R
delegate(U), R, U...) && is(V == Combination!(indices,
ParameterTypeTuple!D)))
{
/* static if(indices.length > 1)
return
bind!(update!(indices,indices[0]))(Curry!(indices[0])(dg,values[0]),values[1..$]);
else static if(indices.length == 1)
return
Curry!(indices[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;
writeln(Arg.stringof);
bind!([0,1])(&xyz,a);
//readln();
}
Thank you very much:)
May 30 2012
And, one more thing
if we have the following code:
template foo (T)
{
auto foo (U) (U arg)
{
}
}
...
foo!(int)('!');
determine whether the compiler that this specialization is to an
external template?
May 30 2012
On Thu, May 31, 2012 at 8:31 AM, Zhenya <zheny list.ru> wrote:
And, one more thing
if we have the following code:
template foo (T)
{
=C2=A0 =C2=A0 =C2=A0 =C2=A0auto foo (U) (U arg)
=C2=A0 =C2=A0 =C2=A0 =C2=A0{
=C2=A0 =C2=A0 =C2=A0 =C2=A0}
}
...
foo!(int)('!');
determine whether the compiler that this specialization is to an external
template?
I'm not sure I understand the question?
May 31 2012
On 31.05.2012 10:31, Zhenya wrote:
And, one more thing
if we have the following code:
template foo (T)
{
auto foo (U) (U arg)
{
}
}
...
foo!(int)('!');
determine whether the compiler that this specialization is to an
external template?
If you happen to be Russian, feel free to include Russian as well. I
might help translate it ;)
As is your question is ... hardly understandable.
--
Dmitry Olshansky
May 31 2012
Вот у нас есть такая конструкция
template foo(T)
{
foo(U)()
{
}
}
Могут ли у компилятора при
инстанциировании возникнуть
трудности с пониманием
какие аргументы к какому шаблону
относятся?
Вопрос у меня возник из-за того,что
когда я применил совет Philippe Sigaud
к своему полному коду компилятор не
захотел его компилировать.Но когда
я поменял имя внутреннего шаблона
все стало хорошо.Это ведь
неправильно?
Jun 01 2012
Вот у нас есть такая конструкция
template foo(T)
{
foo(U)()
{
}
}
Могут ли у компилятора при
инстанциировании возникнуть
трудности с пониманием
какие аргументы к какому шаблону
относятся?
Вопрос у меня возник из-за того,что
когда я применил совет Philippe Sigaud
к своему полному коду компилятор не
захотел его компилировать.Но когда
я поменял имя внутреннего шаблона
все стало хорошо.Это ведь
неправильно?
Jun 01 2012
On Friday, 1 June 2012 at 08:08:19 UTC, Zhenya wrote:Вот у нас есть такая конструкция template foo(T) { foo(U)() { } } Могут ли у компилятора при инстанциировании возникнуть трудности с пониманием какие аргументы к какому шаблону относятся? Вопрос у меня возник из-за того,что когда я применил совет Philippe Sigaud к своему полному коду компилятор не захотел его компилировать.Но когда я поменял имя внутреннего шаблона все стало хорошо.Это ведь неправильно?In other words: Given this construct:template foo(T) { foo(U)() { } }Could there be some problems with compiler not understanding which template argument goes to which template here? The question was born when I started applying Philippe Siguad's advice to my full source code compiler rejected it. But when I change inner tmeplate name it worked - it's no good, is it? Вопрос довольно сложный. Краткий ответ - нет, все идет слева направо, сверху вниз. Есть впрочем одно но - компилятор начинает выводить типы из аргументов только для последнего foo (т.е. U). То есть T в это случае дается сверху (тобой через foo!T(...) ). Впрочем в твоем примере foo не моежт вывести U из аргументов (их нет). Difficult Q. In short - no, it's all left-to-right up-to-bottom. However compiler may deduce types only for lowest foo (i.e. U). T in this case have to provided from above (by you as in foo!T(...)). --- It's me, just trying out web interface.
Jun 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();
}
Jun 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
Jun 01 2012
On Friday, 1 June 2012 at 11:23:48 UTC, Dmitry Olshansky wrote:On 01.06.2012 15:16, Zhenya wrote:В том-то и дело,что (&checker!(int,int,int,int),2,1,4) - аргументы времени выполнения.Значит: bind!([1,0,3])(&checker!(int,int,int,int),2,1,4)(3) но не хочет компилится(Но тогда почему при замене 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(); }
Jun 01 2012
On 01.06.2012 15:40, Zhenya wrote:On Friday, 1 June 2012 at 11:23:48 UTC, Dmitry Olshansky wrote:Лог ошибок в студию. -- Dmitry OlshanskyOn 01.06.2012 15:16, Zhenya wrote:В том-то и дело,что (&checker!(int,int,int,int),2,1,4) - аргументы времени выполнения.Значит: bind!([1,0,3])(&checker!(int,int,int,int),2,1,4)(3) но не хочет компилится(Но тогда почему при замене 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(); }
Jun 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
Jun 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 98It 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
Jun 01 2012
On Friday, 1 June 2012 at 12:38:11 UTC, Dmitry Olshansky wrote:On 01.06.2012 15:47, Zhenya wrote:Error 1 basic type expected, not alias c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 75 Похоже что alias не может быть аргументом времени выполнения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 98It 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.
Jun 01 2012
On 01.06.2012 16:47, Zhenya wrote:On Friday, 1 June 2012 at 12:38:11 UTC, Dmitry Olshansky wrote:ну как же map, filter и тд работают ) ну передавай свой delegate как параметр времени компиляции через !(...) все будет ок ... auto bind(alias dg, V...)(V values)On 01.06.2012 15:47, Zhenya wrote:Error 1 basic type expected, not alias c:\users\zhenya\documents\visual studio 2010\Projects\D\ConsoleApp1\ConsoleApp1\main.d 75 Похоже что alias не может быть аргументом времени выполнения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 98It 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.Bind!(update!(indeces,indeces[0])[1..$]).bind!(Curry! (indeces[0]) (values[0]),values[1..$]);if(is(V == Combination!(indeces,ParameterTypeTuple!D))) { static if(indeces.length > 1) return-- Dmitry Olshanskyelse assert(0); } }
Jun 01 2012
ну как же map, filter и тд работают ) ну передавай свой delegate как параметр времени компиляции через !(...) все будет ок ...нууу так не прикольно. А это часом не бага у DMD?
Jun 01 2012
On 01.06.2012 16:53, Zhenya wrote:beats me.ну как же map, filter и тд работают ) ну передавай свой delegate как параметр времени компиляции через !(...) все будет ок ...нууу так не прикольно.А это часом не бага у DMD?Ну их много, заполни репорт в http://d.puremagic.com/issues/ через пару дней Кенжи Хара пофиксит если это баг ) -- Dmitry Olshansky
Jun 01 2012
On Friday, 1 June 2012 at 12:53:16 UTC, Zhenya wrote:кстати если я заменяю 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]); } } } } на class Bind(alias indeces) { static auto opCall(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..$])(Curry!(indeces[0])(dg,values[0]),values[1..$]); else return Curry!(indeces[0])(dg,values[0]); } } } то вот так Bind!([1,0,3])(&checker!(int,int,int,int),2,1,4)(3); вполне спокойно работает в чем же разница?ну как же map, filter и тд работают ) ну передавай свой delegate как параметр времени компиляции через !(...) все будет ок ...нууу так не прикольно. А это часом не бага у DMD?
Jun 01 2012
Дмитрий,не подскажите как я бы мог проверить не баг ли это?
Jun 02 2012
On 02.06.2012 11:23, Zhenya wrote:Дмитрий,не подскажите как я бы мог проверить не баг ли это?Как я и говорил отписать что это баг. Дальше это дело экспертов по компилятору ) Вот например последние что ты отипсывал, вполне катит для bug-репорта: (только сократи лишний "внешний" код) this doesn't work: 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]); } } } } while this works : class Bind(alias indeces) { static auto opCall(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..$])(Curry!(indeces[0])(dg,values[0]),values[1..$]); else return Curry!(indeces[0])(dg,values[0]); } } } -- Dmitry Olshansky
Jun 02 2012
On 02.06.2012 11:30, Zhenya wrote:Куда отписать-то?)http://d.puremagic.com/issues/ -- Dmitry Olshansky
Jun 02 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();
}
Jun 01 2012









Philippe Sigaud <philippe.sigaud gmail.com> 