www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Algebraic changing type when in associative array

reply rous <email example.com> writes:
I'm defining an Algebraic type like this:
alias Expr = Algebraic!(This[char], string, int);
However, when I create an Expr from an associative array of chars 
and Exprs, the Exprs seem to change from Algebraic to 
VariantN!32LU types. This is illustrated in the following error 
message:
cannot pass argument ex.opIndex(' ') of type VariantN!32LU to 
parameter VariantN!(16LU, This[char], string, int) ex
when I try to call a function that takes an Expr with ex[' '].
If there is no way to ensure that it does not change type, is 
there a way to cast it back?
Feb 04 2020
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
It did not change type.

"Algebraic data type restricted to a closed set of possible types. It's 
an alias for VariantN with an appropriately-constructed maximum size."

https://dlang.org/phobos/std_variant.html#.Algebraic
Feb 04 2020
parent reply rous <email example.com> writes:
On Tuesday, 4 February 2020 at 11:47:49 UTC, rikki cattermole 
wrote:
 It did not change type.

 "Algebraic data type restricted to a closed set of possible 
 types. It's an alias for VariantN with an 
 appropriately-constructed maximum size."

 https://dlang.org/phobos/std_variant.html#.Algebraic
Okay, that makes sense. However, shouldn't it still be the same Algebraic type, and thus an alias for a VariantN with the same maximum size?
Feb 04 2020
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 05/02/2020 12:55 AM, rous wrote:
 On Tuesday, 4 February 2020 at 11:47:49 UTC, rikki cattermole wrote:
 It did not change type.

 "Algebraic data type restricted to a closed set of possible types. 
 It's an alias for VariantN with an appropriately-constructed maximum 
 size."

 https://dlang.org/phobos/std_variant.html#.Algebraic
Okay, that makes sense. However, shouldn't it still be the same Algebraic type, and thus an alias for a VariantN with the same maximum size?
Algebraic doesn't exist. Its a name for your use. This is what an alias is. It does not create a new type, it gives a name to another one. This chapter of the book (free) goes into more detail about alias http://ddili.org/ders/d.en/alias.html
Feb 04 2020
parent reply rous <email example.com> writes:
On Tuesday, 4 February 2020 at 12:05:16 UTC, rikki cattermole 
wrote:
 On 05/02/2020 12:55 AM, rous wrote:
 On Tuesday, 4 February 2020 at 11:47:49 UTC, rikki cattermole 
 wrote:
 It did not change type.

 "Algebraic data type restricted to a closed set of possible 
 types. It's an alias for VariantN with an 
 appropriately-constructed maximum size."

 https://dlang.org/phobos/std_variant.html#.Algebraic
Okay, that makes sense. However, shouldn't it still be the same Algebraic type, and thus an alias for a VariantN with the same maximum size?
Algebraic doesn't exist. Its a name for your use. This is what an alias is. It does not create a new type, it gives a name to another one. This chapter of the book (free) goes into more detail about alias http://ddili.org/ders/d.en/alias.html
This is an example program that illustrates the issue: import std.variant: Algebraic, This; import std.stdio: writeln; alias Foo = Algebraic!(This[], int); void main() { Foo x = 5; Foo y = 10; Foo z = [x,y]; pragma(msg, typeof(x)); pragma(msg, typeof(y)); pragma(msg, typeof(z)); pragma(msg, typeof(z[0])); } At compile time, it prints VariantN!(16LU, This[], int) three times and then VariantN!32LU.
Feb 04 2020
parent Paul Backus <snarwin gmail.com> writes:
On Wednesday, 5 February 2020 at 01:06:46 UTC, rous wrote:
 This is an example program that illustrates the issue:

 import std.variant: Algebraic, This;
 import std.stdio: writeln;
 alias Foo = Algebraic!(This[], int);
 void main()
 {
     Foo x = 5;
     Foo y = 10;
     Foo z = [x,y];
     pragma(msg, typeof(x));
     pragma(msg, typeof(y));
     pragma(msg, typeof(z));
     pragma(msg, typeof(z[0]));
 }
 At compile time, it prints VariantN!(16LU, This[], int) three 
 times and then VariantN!32LU.
The problem is that you are indexing directly into the Algebraic, using VariantN.opIndex [1], which returns a generic, non-Algebraic Variant. Instead, you should use visit [2] or tryVisit [3] to access the array contained inside the Algebraic, and index into that. For example: auto w = z.tryVisit!((Foo[] arr) => arr[0]); static assert(is(typeof(w) == Foo)); [1] https://dlang.org/phobos/std_variant.html#.VariantN.opIndex [2] https://dlang.org/phobos/std_variant.html#.visit [3] https://dlang.org/phobos/std_variant.html#.tryVisit
Feb 04 2020
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Tuesday, 4 February 2020 at 11:45:50 UTC, rous wrote:
 I'm defining an Algebraic type like this:
 alias Expr = Algebraic!(This[char], string, int);
 However, when I create an Expr from an associative array of 
 chars and Exprs, the Exprs seem to change from Algebraic to 
 VariantN!32LU types. This is illustrated in the following error 
 message:
 cannot pass argument ex.opIndex(' ') of type VariantN!32LU to 
 parameter VariantN!(16LU, This[char], string, int) ex
 when I try to call a function that takes an Expr with ex[' '].
 If there is no way to ensure that it does not change type, is 
 there a way to cast it back?
Can you post an example program that illustrates the error? You shouldn't be getting two different sizes (16 and 32) for the same Algebraic type.
Feb 04 2020
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 05/02/2020 2:11 AM, Paul Backus wrote:
 On Tuesday, 4 February 2020 at 11:45:50 UTC, rous wrote:
 I'm defining an Algebraic type like this:
 alias Expr = Algebraic!(This[char], string, int);
 However, when I create an Expr from an associative array of chars and 
 Exprs, the Exprs seem to change from Algebraic to VariantN!32LU types. 
 This is illustrated in the following error message:
 cannot pass argument ex.opIndex(' ') of type VariantN!32LU to 
 parameter VariantN!(16LU, This[char], string, int) ex
 when I try to call a function that takes an Expr with ex[' '].
 If there is no way to ensure that it does not change type, is there a 
 way to cast it back?
Can you post an example program that illustrates the error? You shouldn't be getting two different sizes (16 and 32) for the same Algebraic type.
I missed this when I commented previously as there is two questions in the original post. My bad rous!
Feb 04 2020