www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Partial application of compile time args type deduction

reply QAston <qaston gmail.com> writes:
Hi,

I have the following code:

auto appendMapped(alias f, R, T)(R r, T elem) {
	r ~= f(elem);
	return r;
}

int minus(int i) {
	return -i;
}

unittest {
	int[] ar;
         // here I do partial application of minus function
	alias appendMinus(S,T) = appendMapped!(minus, S, T);
	assert (appendMinus!(int[], int)(ar, 10) == [-10]); // compiles
	assert (appendMinus(ar, 10) == [-10]); // doesn't compile
}

Which gives me following error:
Error: template transduced.__unittestL111_2.appendMinus cannot 
deduce function from argument types !()(int[], int), candidates 
are:  transduced.__unittestL111_2.appendMinus(S, T)

Is there a way to do partial template arg application which does 
template type deduction correctly?
Jan 19
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 01/19/2016 03:37 PM, QAston wrote:
 Hi,

 I have the following code:

 auto appendMapped(alias f, R, T)(R r, T elem) {
      r ~= f(elem);
      return r;
 }

 int minus(int i) {
      return -i;
 }

 unittest {
      int[] ar;
          // here I do partial application of minus function
      alias appendMinus(S,T) = appendMapped!(minus, S, T);
      assert (appendMinus!(int[], int)(ar, 10) == [-10]); // compiles
      assert (appendMinus(ar, 10) == [-10]); // doesn't compile
 }

 Which gives me following error:
 Error: template transduced.__unittestL111_2.appendMinus cannot deduce
 function from argument types !()(int[], int), candidates are:
 transduced.__unittestL111_2.appendMinus(S, T)

 Is there a way to do partial template arg application which does
 template type deduction correctly?
I don't know whether it's possible with 'alias' but the following trivial wrapper works: auto appendMinus(S,T)(S s, T t) { return appendMapped!minus(s, t); } Ali
Jan 19
parent reply QAston <qaston gmail.com> writes:
On Wednesday, 20 January 2016 at 00:12:16 UTC, Ali Çehreli wrote:
 On 01/19/2016 03:37 PM, QAston wrote:
 Hi,

 I have the following code:

 auto appendMapped(alias f, R, T)(R r, T elem) {
      r ~= f(elem);
      return r;
 }

 int minus(int i) {
      return -i;
 }

 unittest {
      int[] ar;
          // here I do partial application of minus function
      alias appendMinus(S,T) = appendMapped!(minus, S, T);
      assert (appendMinus!(int[], int)(ar, 10) == [-10]); // 
 compiles
      assert (appendMinus(ar, 10) == [-10]); // doesn't compile
 }

 Which gives me following error:
 Error: template transduced.__unittestL111_2.appendMinus cannot 
 deduce
 function from argument types !()(int[], int), candidates are:
 transduced.__unittestL111_2.appendMinus(S, T)

 Is there a way to do partial template arg application which 
 does
 template type deduction correctly?
I don't know whether it's possible with 'alias' but the following trivial wrapper works: auto appendMinus(S,T)(S s, T t) { return appendMapped!minus(s, t); } Ali
I think I've reduced my case too much: the wrapper needs to be generic so that I can do something like this (basically a closure but compile time) void wrapper(minus) { alias appendMinus(S,T) = appendMapped!(minus, S, T); assert (appendMinus(ar, 10) == [-10]); } Anyway, thanks for help Ali, love your book:)
Jan 19
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 01/19/2016 04:22 PM, QAston wrote:
 On Wednesday, 20 January 2016 at 00:12:16 UTC, Ali Çehreli wrote:
 On 01/19/2016 03:37 PM, QAston wrote:
 Hi,

 I have the following code:

 auto appendMapped(alias f, R, T)(R r, T elem) {
      r ~= f(elem);
      return r;
 }

 int minus(int i) {
      return -i;
 }

 unittest {
      int[] ar;
          // here I do partial application of minus function
      alias appendMinus(S,T) = appendMapped!(minus, S, T);
      assert (appendMinus!(int[], int)(ar, 10) == [-10]); // compiles
      assert (appendMinus(ar, 10) == [-10]); // doesn't compile
 }

 Which gives me following error:
 Error: template transduced.__unittestL111_2.appendMinus cannot deduce
 function from argument types !()(int[], int), candidates are:
 transduced.__unittestL111_2.appendMinus(S, T)

 Is there a way to do partial template arg application which does
 template type deduction correctly?
I don't know whether it's possible with 'alias' but the following trivial wrapper works: auto appendMinus(S,T)(S s, T t) { return appendMapped!minus(s, t); } Ali
I think I've reduced my case too much: the wrapper needs to be generic so that I can do something like this (basically a closure but compile time) void wrapper(minus) { alias appendMinus(S,T) = appendMapped!(minus, S, T); assert (appendMinus(ar, 10) == [-10]); } Anyway, thanks for help Ali, love your book:)
Is this it? If so, is it already in std.functional? (I could not find it. :) ) auto appendMapped(alias f, R, T)(R r, T elem) { r ~= f(elem); return r; } int minus(int i) { return -i; } unittest { int[] ar; template bindFirstParam(alias original, alias func, Args...) { auto bindFirstParam(Args...)(Args args) { return original!(func, Args)(args); } } alias appendMinus = bindFirstParam!(appendMapped, minus); assert (appendMinus!(int[], int)(ar, 10) == [-10]); // compiles assert (appendMinus(ar, 10) == [-10]); // doesn't compile } void main() { } Ali
Jan 19
parent QAston <qaston gmail.com> writes:
On Wednesday, 20 January 2016 at 00:50:49 UTC, Ali Çehreli wrote:
 On 01/19/2016 04:22 PM, QAston wrote:
 [...]
Is this it? If so, is it already in std.functional? (I could not find it. :) ) auto appendMapped(alias f, R, T)(R r, T elem) { r ~= f(elem); return r; } int minus(int i) { return -i; } unittest { int[] ar; template bindFirstParam(alias original, alias func, Args...) { auto bindFirstParam(Args...)(Args args) { return original!(func, Args)(args); } } alias appendMinus = bindFirstParam!(appendMapped, minus); assert (appendMinus!(int[], int)(ar, 10) == [-10]); // compiles assert (appendMinus(ar, 10) == [-10]); // doesn't compile } void main() { } Ali
Works, thanks!
Jan 20