Partial application of compile time args type deduction

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jan 19 16:50:49 PST 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



More information about the Digitalmars-d-learn mailing list