digitalmars.D.learn - array of delegates
- Alex (58/58) Apr 13 2016 Hi at all!
- David Skluzacek (27/27) Apr 13 2016 So, that message is a pretty cryptic, but the problem there is
- Alex (11/38) Apr 13 2016 Ah, ok... so, it was my mistake due to runtime <-> compile time
- =?UTF-8?Q?Ali_=c3=87ehreli?= (12/14) Apr 13 2016 I think you want to generate a different delegate for each element where...
- Alex (8/23) Apr 13 2016 Yes exactly!
Hi at all! Having read this: http://forum.dlang.org/post/mailman.2415.1354291433.5162.digitalmars-d-learn puremagic.com still have a problem... Lets begin with what works: enum Props{p1, p2} class AA { int[] arr1; int[] arr2; this() { //arbitrary values... arr1 = [9, 6, 33, 42, 58]; arr2 = [2, 3, 44, 28, 77]; } auto Foo(int i, Props p) { with(Props) { final switch(p) { case p1: { return arr1[i]; } break; case p2: { return arr2[i]; } break; } } } } main() { int indarr[] = [0, 1, 2, 3, 4]; import std.stdio; import std.functional; AA aa = new AA(); int delegate(int, Props) sg; sg = &aa.Foo; alias M3 = partial!(sg, 3); writeln(M3(Props.p1)); writeln(M3(Props.p2)); } So far, so good. But now the question: if I try import std.algorithm; indarr.map!(a => partial!(sg, a)); I get an error, like Error: partial (Props _param_0) is not callable using argument types (). Do you have a hint, what I'm doing wrong? For the motivation: In this way I would like to store some "links" to data I have without having to define a struct, which incorporate the data. The struct itself is not the problem, but how the data is handled is not known by the struct, but only by the class AA, so the expressions inside the switch should not (?) lie inside the struct.
Apr 13 2016
So, that message is a pretty cryptic, but the problem there is that map does its thing at runtime, but partial is a template and must be instantiated at compile time. Instead you can use std.meta.staticMap, by doing something like this: ---- void main() { import std.stdio; import std.functional; import std.meta; AA aa = new AA(); int delegate(int, Props) sg; sg = &aa.Foo; template partialSG(alias a) { alias partialSG = partial!(sg, a); } alias indarr = AliasSeq!(0, 1, 2, 3, 4); alias funs = staticMap!(partialSG, indarr); foreach (fun; funs) { writeln( fun(Props.p1) ); writeln( fun(Props.p2) ); } }
Apr 13 2016
On Thursday, 14 April 2016 at 05:54:38 UTC, David Skluzacek wrote:So, that message is a pretty cryptic, but the problem there is that map does its thing at runtime, but partial is a template and must be instantiated at compile time. Instead you can use std.meta.staticMap, by doing something like this: ---- void main() { import std.stdio; import std.functional; import std.meta; AA aa = new AA(); int delegate(int, Props) sg; sg = &aa.Foo; template partialSG(alias a) { alias partialSG = partial!(sg, a); } alias indarr = AliasSeq!(0, 1, 2, 3, 4); alias funs = staticMap!(partialSG, indarr); foreach (fun; funs) { writeln( fun(Props.p1) ); writeln( fun(Props.p2) ); } }Ah, ok... so, it was my mistake due to runtime <-> compile time templates. Thanks. But, this would help, only if I know the total amount of my elements at compile time. Say, the length of the indarr would be known. What if I don't have this information? In reality, this information is already known for the constructors of my classes. But it seems very strange to me, to let the user recompile the program each time with some compiler flag in order to deliver this parameter a step prior to this.
Apr 13 2016
On 04/13/2016 04:39 PM, Alex wrote:import std.algorithm; indarr.map!(a => partial!(sg, a));I think you want to generate a different delegate for each element where the first argument to sg is the value of that element (0, 1, etc.). Since the second element of sg is a Props, you then want to call those delegates with a Props value (e.g. Props.p1). The following works: import std.algorithm; auto mapped = indarr .map!(a => (Props p) => sg(a, p)) .map!(d => d(Props.p1)); writeln(mapped); Ali
Apr 13 2016
On Thursday, 14 April 2016 at 06:27:29 UTC, Ali Çehreli wrote:On 04/13/2016 04:39 PM, Alex wrote:Yes exactly! The idea is to save auto mapped = indarr.map!(a => (Props p) => sg(a, p)); for later use and use it then by mapped[someIndex](Props.p1) or mapped[someIndex](Props.p2) when needed. Thank you very much! :)import std.algorithm; indarr.map!(a => partial!(sg, a));I think you want to generate a different delegate for each element where the first argument to sg is the value of that element (0, 1, etc.). Since the second element of sg is a Props, you then want to call those delegates with a Props value (e.g. Props.p1). The following works: import std.algorithm; auto mapped = indarr .map!(a => (Props p) => sg(a, p)) .map!(d => d(Props.p1)); writeln(mapped); Ali
Apr 13 2016