www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to assign and compare arrays to SumType?

reply confuzzled <con fuzzled.com> writes:
Comparison between a Variant and an array is straightforward. How 
does one accomplish the same between a SumType and an array?

```d
import std.variant;
import std.sumtype;
import std.stdio;

struct S
{
     SumType!(double[]) data;  // {1}
}

void main()
{
     Variant v = [1.7, 2.7, 3.7, 4.7, 5.7];
     assert(v == [1.7, 2.7, 3.7, 4.7, 5.7]);

     S s;
     s.data = [1.7, 2.7, 3.7, 4.7, 5.7]; // {2}
     assert(s.data == [1.7, 2.7, 3.7, 4.7, 5.7]);
}
```

Resulting Error:

 var.d(17): Error: template \`opEquals\` is not callable using 
 argument types `!()(double[])`
 /Users/anju/dlang/dmd-2.109.0-beta.1/osx/bin/../../src/phobos
std/sumtype.d(712):        Candidate is: `opEquals(this This, Rhs)(auto ref Rhs
rhs)`
  with `This = SumType!(double[]),
       Rhs = double[]`
  must satisfy the following constraint:
`       !is(CommonType!(This, Rhs) == void)`
Also, assuming that {1} read "SumType!(double)[] data;", what would be the proper way to accomplish the assignment at {2} and the subsequent comparison. Thanks, --confuzzled P.S. Is news.digitalmars.com still operational? I'm unable to access it through Thunderbird.
Jun 11
next sibling parent confuzzled <con fuzzled.com> writes:
On Tuesday, 11 June 2024 at 16:41:46 UTC, confuzzled wrote:
 Also, assuming that {1} read "SumType!(double)[] data;", what 
 would be the proper way to accomplish the assignment at {2} and 
 the subsequent comparison.
Not sure how to do solve the fist part of the question yet but I was able to get this part done. s.data = [SumType!double(1.7), SumType!double(2.7), SumType!double(3.7), SumType!double(4.7), SumType!double(5.7)]; assert(s.data == [SumType!double(1.7), SumType!double(2.7), SumType!double(3.7), SumType!double(4.7), SumType!double(5.7)]); Wander if there is a more succinct way to do this?
 P.S. Is news.digitalmars.com still operational? I'm unable to 
 access it through Thunderbird.
Jun 11
prev sibling next sibling parent reply confuzzled <con fuzzled.com> writes:
On Tuesday, 11 June 2024 at 16:41:46 UTC, confuzzled wrote:
 Comparison between a Variant and an array is straightforward. 
 How does one accomplish the same between a SumType and an array?
Okay, this is what I came up with. Just a sanity check please. Did I do this correctly? Is there something I'm overlooking? ```d import std.variant; import std.sumtype; import std.traits: isArray; struct S { SumType!(double[]) data; bool opEquals(T)(auto ref const T s) const if (isArray!T) { return data == typeof(data)(s); } void opAssign(T)(T value) if (isArray!T) { data = typeof(data)(value); } this(T)(T value) if (isArray!T) { opAssign(value); } } void main() { Variant v = [1.7, 2.7, 3.7, 4.7, 5.7]; assert(v == [1.7, 2.7, 3.7, 4.7, 5.7]); S s = [1.7, 2.7, 3.7, 4.7, 5.7]; assert(s == [1.7, 2.7, 3.7, 4.7, 5.7]); } ``` Thanks, --confuzzled
Jun 11
parent Anonymouse <zorael gmail.com> writes:
On Tuesday, 11 June 2024 at 18:26:50 UTC, confuzzled wrote:
 On Tuesday, 11 June 2024 at 16:41:46 UTC, confuzzled wrote:
 Comparison between a Variant and an array is straightforward. 
 How does one accomplish the same between a SumType and an 
 array?
Okay, this is what I came up with. Just a sanity check please. Did I do this correctly? Is there something I'm overlooking?
It's enough to just make the whole array another `SumType!(double[])`. ```d void main() { Variant v = [1.7, 2.7, 3.7, 4.7, 5.7]; assert(v == [1.7, 2.7, 3.7, 4.7, 5.7]); S s; s.data = [1.7, 2.7, 3.7, 4.7, 5.7]; // {2} assert(s.data == SumType!(double[])([1.7, 2.7, 3.7, 4.7, 5.7])); } ``` Or better yet, to avoid redundantly spelling out the type; ```d assert(s.data == typeof(s.data)([1.7, 2.7, 3.7, 4.7, 5.7])); ```
Jun 11
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On Tuesday, 11 June 2024 at 16:41:46 UTC, confuzzled wrote:
 Comparison between a Variant and an array is straightforward. 
 How does one accomplish the same between a SumType and an array?

 ```d
 import std.variant;
 import std.sumtype;
 import std.stdio;

 struct S
 {
     SumType!(double[]) data;  // {1}
 }

 void main()
 {
     Variant v = [1.7, 2.7, 3.7, 4.7, 5.7];
     assert(v == [1.7, 2.7, 3.7, 4.7, 5.7]);

     S s;
     s.data = [1.7, 2.7, 3.7, 4.7, 5.7]; // {2}
     assert(s.data == [1.7, 2.7, 3.7, 4.7, 5.7]);
 }
 ```

 Resulting Error:

 var.d(17): Error: template \`opEquals\` is not callable using 
 argument types `!()(double[])`
 /Users/anju/dlang/dmd-2.109.0-beta.1/osx/bin/../../src/phobos
std/sumtype.d(712):        Candidate is: `opEquals(this This, Rhs)(auto ref Rhs
rhs)`
  with `This = SumType!(double[]),
       Rhs = double[]`
  must satisfy the following constraint:
`       !is(CommonType!(This, Rhs) == void)`
Also, assuming that {1} read "SumType!(double)[] data;", what would be the proper way to accomplish the assignment at {2} and the subsequent comparison.
`SumType` requires you unwrap to the correct type in order to use it. The function that unwraps a `SumType` is called `match`. The `match` function accepts a sumtype and a list of processors. Each processor is tried in order, based on the actual stored type, and the first one that compiles will be used. Your `SumType` has only one type, but just to illustrate how it would work: ```d assert(s.data.match!((double[] darr) => darr == [1.7, 2.7, 3.7, 4.7, 5.7])); ``` What this is doing is, if the actual type is a `double[]`, then call the first function, and return it's value (a boolean). Because there are no other types, this will work. If you have more than one type, your list of lambdas must be exhaustive. That is, at least one of the functions must match for each type. And also, functions that won't ever be used are rejected. Let's see how it works if you want to both check that the value is a `double[]` and that it matches your value: ```d SumType!(double[], int) s = [1.7, 2.7, 3.7, 4.7, 5.7]; assert(s.data.match!( (double[] darr) => darr == [1.7, 2.7, 3.7, 4.7, 5.7]), _ => false // any other type ) ); s = 5; // switch to int assert(!s.data.match!( (double[] darr) => darr == [1.7, 2.7, 3.7, 4.7, 5.7]), _ => false // any other type ) ); ``` `SumTypes` take some getting used to. It can get pretty verbose to use `match`. -Steve
Jun 11
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On Tuesday, 11 June 2024 at 22:54:50 UTC, Steven Schveighoffer 
wrote:

 Let's see how it works if you want to both check that the value 
 is a `double[]` and that it matches your value:

 ```d
 SumType!(double[], int) s = [1.7, 2.7, 3.7, 4.7, 5.7];
 assert(s.data.match!(
 ```
This should be `s.match!(...`, I just was copy-pasting. -Steve
Jun 11