digitalmars.D.learn - Function template argument deduction
- Paul Backus (40/40) Apr 06 2018 I'm playing around with functional programming in D, and have run
- Uknown (4/7) Apr 06 2018 I don't see the error you are talking about:
- Paul Backus (3/6) Apr 06 2018 Compile with -unittest.
- Uknown (12/19) Apr 06 2018 Now I feel silly. Anyway, I played around with your code. One
- =?UTF-8?Q?Ali_=c3=87ehreli?= (11/31) Apr 06 2018 I played with it as well by hacking the following:
- Paul Backus (15/20) Apr 07 2018 Interesting. Looks like this is an issue with aliases, because I
- Paul Backus (7/21) Apr 07 2018 Looks like this is the same problem described in issue 1807:
I'm playing around with functional programming in D, and have run into a problem with the following code: --- list.d import std.variant: Algebraic, This, visit; import std.typecons: Tuple, tuple; struct Nil {} alias List(T) = Algebraic!( Nil, Tuple!(T, "head", This*, "tail") ); alias Cons(T) = Tuple!(T, "head", List!T*, "tail"); List!T* list(T)(T[] items...) { if (items.length == 0) return new List!T(Nil()); else return new List!T(Cons!T(items[0], list(items[1..$]))); } string list2string(T)(List!T list) { import std.stdio: write; list.visit!( (Nil _) => "nil", (Cons!T cons) => "cons(" ~ cons.head ~ ", " ~ list2string(*cons.tail) ~ ")" ); } unittest { List!int* myList = list(1, 2, 3); assert(list2string(*myList) == "cons(1, cons(2, cons(3, nil)))"); } --- The error I get is "template list.list2string cannot deduce function from argument types [...]"; i.e., the compiler can't figure out that T is supposed to be 'int'. My question is, why not? Is there anything I can do to get this to work? The compiler seems to be able to handle this sort of thing in general (e.g., it can deduce 'int' from an argument of type 'Tuple!(int, int)'), so what makes this particular case fail?
Apr 06 2018
On Saturday, 7 April 2018 at 05:10:05 UTC, Paul Backus wrote:I'm playing around with functional programming in D, and have run into a problem with the following code: [...]I don't see the error you are talking about: https://run.dlang.io/is/XWPIc1 Are you using the latest compiler?
Apr 06 2018
On Saturday, 7 April 2018 at 05:46:07 UTC, Uknown wrote:I don't see the error you are talking about: https://run.dlang.io/is/XWPIc1 Are you using the latest compiler?Compile with -unittest. And yes; I'm using DMD 2.079.0.
Apr 06 2018
On Saturday, 7 April 2018 at 05:58:10 UTC, Paul Backus wrote:On Saturday, 7 April 2018 at 05:46:07 UTC, Uknown wrote:Now I feel silly. Anyway, I played around with your code. One thing I found was `cons.head` returns a `T`, which can't be appended to a string. You can fix this with `cons.head.to!string`, where `to` is from std.conv. I'm not sure why IFTI isn't deducing `T` to be `int` though. Hopefully some one else can help out here. What I did notice though is that when `string list2string(T)(List!T list)` was changed to `string list2string(T)(VariantN!(16LU, Nil, Tuple!(T, "head", This*, "tail")) list)` The compiler correctly deduce `T` to be `int`I don't see the error you are talking about: https://run.dlang.io/is/XWPIc1 Are you using the latest compiler?Compile with -unittest. And yes; I'm using DMD 2.079.0.
Apr 06 2018
On 04/06/2018 11:26 PM, Uknown wrote:On Saturday, 7 April 2018 at 05:58:10 UTC, Paul Backus wrote:I played with it as well by hacking the following: string list2string(L)(L list) { import std.traits : TemplateArgsOf; alias T = TemplateArgsOf!L[2][0]; // ... } I hit the same problem that you describe. (Additionally, list2string does not return anything.) AliOn Saturday, 7 April 2018 at 05:46:07 UTC, Uknown wrote:Now I feel silly. Anyway, I played around with your code. One thing I found was `cons.head` returns a `T`, which can't be appended to a string. You can fix this with `cons.head.to!string`, where `to` is from std.conv. I'm not sure why IFTI isn't deducing `T` to be `int` though. Hopefully some one else can help out here. What I did notice though is that when `string list2string(T)(List!T list)` was changed to `string list2string(T)(VariantN!(16LU, Nil, Tuple!(T, "head", This*, "tail")) list)` The compiler correctly deduce `T` to be `int`I don't see the error you are talking about: https://run.dlang.io/is/XWPIc1 Are you using the latest compiler?Compile with -unittest. And yes; I'm using DMD 2.079.0.
Apr 06 2018
On Saturday, 7 April 2018 at 06:26:24 UTC, Uknown wrote:What I did notice though is that when `string list2string(T)(List!T list)` was changed to `string list2string(T)(VariantN!(16LU, Nil, Tuple!(T, "head", This*, "tail")) list)` The compiler correctly deduce `T` to be `int`Interesting. Looks like this is an issue with aliases, because I get the error with this code too: --- test.d import std.typecons: Tuple, tuple; alias Pair(T) = Tuple!(T, T); void foo(T)(Pair!T p) { return; } unittest { Pair!int x = tuple(1, 2); foo(x); } ---
Apr 07 2018
On Saturday, 7 April 2018 at 14:02:55 UTC, Paul Backus wrote:Interesting. Looks like this is an issue with aliases, because I get the error with this code too: --- test.d import std.typecons: Tuple, tuple; alias Pair(T) = Tuple!(T, T); void foo(T)(Pair!T p) { return; } unittest { Pair!int x = tuple(1, 2); foo(x); } ---Looks like this is the same problem described in issue 1807: https://issues.dlang.org/show_bug.cgi?id=1807 I'm not sure what D was like when Martin Nowak made the most recent comment on that issue, in 2012, but alias templates do have their own dedicated language construct now, so maybe this is worth revisiting.
Apr 07 2018