How can I express the type '(int) => int' where it is a function or a delegate
Puming via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Jul 15 23:22:36 PDT 2014
On Wednesday, 16 July 2014 at 04:10:13 UTC, Rikki Cattermole
wrote:
> On 16/07/2014 3:50 p.m., Puming wrote:
>> I'd like to have a Command class, where their is a name and a
>> handler
>> field:
>>
>> ```d
>> class Command
>> {
>> string name;
>> string delegate(string[]) handler;
>> }
>> ```
>>
>> this is ok, but sometimes I want the handler also accept a
>> function
>> (lambdas are init to functions if no capture of outer scope
>> variables
>> are present), but it can't.
>>
>> So I'd like to generalize the Command to a template, the best
>> I've got
>> sofar:
>>
>> ```d
>>
>> alias string delegate(string[]) HandlerDele;
>> alias string function(string[]) HandlerFunc;
>>
>> class Command(T) if (is (T HandlerDele) || is (T HandlerFunc))
>> {
>> immutable {
>> string name;
>> T handler;
>> }
>>
>> this(string name, T handler)
>> {
>> this.name = name;
>> this.handler = handler;
>> }
>>
>> }
>>
>> void main()
>> {
>>
>> HandlerFunc f = xs => xs[0]; // just a test
>> auto cmd = new Command!HandlerFunc("echo", f);
>> }
>> ```
>>
>> I've got several questions about this:
>>
>> 1. I cant ignore `HandlerFunc` when initiating cmd:
>>
>> ```d
>> auto cmd = new Command("echo", f); // Error: class
>> dshell.command.Command(T) if (is(T HandlerDele) || is(T
>> HandlerFunc)) is
>> used as a type
>> ```
>>
>> Can DMD automatically infer the type here?
>>
>> 2. Is this the right way to do this?
>>
>> 3. I'd like a unified description of `a function pointer or a
>> delegate`,
>> and from the experience of lambda, it seems the syntax of
>> lamdba is
>> really useful here, if we have that, then instead of:
>>
>> ```d
>> void execute(T)(Context cxt, T handler) if (is (T HandlerFunc)
>> || is (T
>> HandlerDele))
>> {
>> //...
>> }
>>
>> we could define a function that accepts a function/delegate
>> like this:
>>
>> ```d
>>
>> void execute(T : string[] => string)(Context cxt, T handler)
>> {
>> //...
>> }
>>
>> // in main
>> ctx.execute(xs => xs[0]);
>
> Or using std.functional toDelegate you could convert the
> function into a delegate.
>
> class Command {
> string name;
> string delegate(string[]) handler;
>
> this(string name, string delegate(string[]) handler) {
> this.name = name;
> this.handler = handler;
> }
>
> this(string name, string function(string[]) handler) {
> import std.functional : toDelegate;
> this.name = name;
> this.handler = toDelegate(handler);
> }
> }
>
> Just keep in mind, you can't go the opposite way.
Thanks. I wonder if functions could implicitly convert to
delegates...but toDelegate is OK.
Also, after another dig into the language docs, I found:
> The .ptr property of a delegate will return the frame pointer
> value as a void*.
> The .funcptr property of a delegate will return the function
> pointer value as a function type.
> Future directions: Function pointers and delegates may merge
> into a common syntax and be interchangeable with each other.
Wonder how that would happen.
More information about the Digitalmars-d-learn
mailing list