std.functional:partial - disambiguating templated functions

John Colvin via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Oct 4 13:26:50 PDT 2015


On Sunday, 4 October 2015 at 19:12:51 UTC, Laeeth Isharc wrote:
> On Sunday, 4 October 2015 at 18:24:08 UTC, John Colvin wrote:
>> On Sunday, 4 October 2015 at 18:08:55 UTC, Laeeth Isharc wrote:
>>> On Sunday, 4 October 2015 at 17:17:14 UTC, Laeeth Isharc 
>>> wrote:
>>>> On Sunday, 4 October 2015 at 16:37:34 UTC, John Colvin wrote:
>>>>> On Sunday, 4 October 2015 at 15:45:55 UTC, Laeeth Isharc 
>>>>> wrote:
>>>>>> How do I persuade partial to tie itself to the appropriate 
>>>>>> overload?
>>>> ---
>>>>> As far as I can see std.functional.partial only does one 
>>>>> argument at a time.
>>>>>
>>>>> bars=partial!(partial!(partial!(slurpBars!BarType, 
>>>>> filename), startDate), endDate);
>>>>>
>>>>> or maybe, I'm not sure, but maybe you can do:
>>>>>
>>>>> bars=partial!(slurpBars!BarType, AliasSeq!(filename, 
>>>>> startDate, endDate));
>>>>>
>>>>> If you find you really need to manually mess with 
>>>>> overloads, use http://dlang.org/traits.html#getOverloads. 
>>>>> You may have to wrap it in AliasSeq in some situations due 
>>>>> to grammar/parser constraints.
>>>> fwiw - still doesn't work (whether I use alias or auto, 
>>>> trying each of your solutions).  I'll look at getOverloads.
>>>
>>> How do I distinguish between two overloads that return the 
>>> same type but have different arguments?  It looks like 
>>> getOverloads only deals with cases where the return type is 
>>> different, judging by the docs.
>>
>> getOverloads should give you all the overloads of a function, 
>> whether they return the same or different types.  The example 
>> in the docs just happens to have different types.
>>
>> In general, return types are not considered when talking about 
>> overloads. For example, two functions that take the same 
>> arguments but have different return types are not overloaded, 
>> they are in conflict.
>
> Thanks for this.  The only problem then is how to manipulate 
> what getOverloads returns.  (No need to do this now as it's not 
> worth it - I just wanted to try using partial if it wasn't too 
> much work.  easier just to make an alternate declaration with 
> the type in its name).
>
> Is this not a bug in the implementation of partial?
>
> import std.functional;
> import std.stdio;
>
> void bish(T)(string arg, string barg)
> {
> 	writefln("bishs: %s, %s",arg,barg,to!T);
> }
> void bish(T)(int argi, string barg)
> {
> 	writefln("bishi: %s, %s",argi,barg.to!T);
> }
>
> void main(string[] args)
> {
> 	alias b=partial!(bish!string,"hello"); // this line does not 
> compile
> 	alias c=partial!(b,"therex");
> 	b("there");
> 	c();
> }
>
> [laeeth at engine marketdata]$ dmd partial.d
> partial.d(15): Error: template partial.bish matches more than 
> one template declaration:
> partial.d(4):     bish(T)(string arg, string barg)
> and
> partial.d(8):     bish(T)(int argi, string barg)
>
>
> partial knows which overload to call - I told it!

The problem happens before partial. Something like

alias b = bish!string;

is an error, because it matches both templates. For some reason 
if you call it directly, e.g.

bish!string("","");

that's ok, but I have no idea why.


What you can do, is this:

template bish(T)
{
	void bish(string arg, string barg)
	{
		writefln("bishs: %s, %s",arg,barg.to!T);
	}
	void bish(int argi, string barg)
	{
		writefln("bishi: %s, %s",argi,barg.to!T);
	}
}

which is just a template containing an overload set, which is no 
problem.

Or:

void bish0(T)(string arg, string barg)
{
	writefln("bishs: %s, %s",arg,barg.to!T);
}
void bish1(T)(int argi, string barg)
{
	writefln("bishi: %s, %s",argi,barg.to!T);
}

alias bishStr = bish0!string;
alias bishStr = bish1!string;

void main(string[] args)
{
	alias b=partial!(bishStr,"hello");
	alias c=partial!(b,"therex");
	b("there");
	c();
}

Or:

void bish0(T)(string arg, string barg)
{
	writefln("bishs: %s, %s",arg,barg.to!T);
}
void bish1(T)(int argi, string barg)
{
	writefln("bishi: %s, %s",argi,barg.to!T);
}

template bish(T)
{
	alias tmp = bish0!T;
	alias tmp = bish1!T;
	alias bish = tmp;
}

void main(string[] args)
{
	alias b=partial!(bish!string, "hello");
	alias c=partial!(b,"therex");
	b("there");
	c();
}


More information about the Digitalmars-d-learn mailing list