Thread overview
Partial application of compile time args type deduction
Jan 19, 2016
QAston
Jan 20, 2016
Ali Çehreli
Jan 20, 2016
QAston
Jan 20, 2016
Ali Çehreli
Jan 20, 2016
QAston
January 19, 2016
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?
January 19, 2016
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

January 20, 2016
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:)
January 19, 2016
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

January 20, 2016
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!