Tagged unions [Was: What's wrong with std.variant.Variant?]

Paul Backus snarwin at gmail.com
Tue Jun 16 13:52:08 UTC 2020


On Tuesday, 16 June 2020 at 12:58:50 UTC, Dukc wrote:
> On Tuesday, 16 June 2020 at 12:21:56 UTC, Paul Backus wrote:
>> If it's not too much trouble, can you give an example of the 
>> kind of thing you'd like to be able to do?
>
> No problem. This is directly from real code. The idea is that I 
> have a vector shape `vecImage.front` and I want to figure out 
> whether I need to reverse it, so that it will run in wanted 
> direction `newDir`. However, the `determineCycleDirection` 
> function is not perfect, so this resulted:

The most straightforward way to do this with SumType is to use a 
variable to track whether an early return is needed:

     const currentDir = 
vecImage.front.save.determineCycleDirection;
     auto errRes; // replace with appropriate type

     bool err = currentDir.match!(
         (Indifferent _) {
             turnNeeded = 0;
             return false;
         },
         (SelfCrossed _) {
             errRes = 
Message.directionSearchSelfCross(fileName).only.array;
             return true;
         },
         (Timeout _) {
             errRes = 
Message.directionSearchTimeout(fileName).only.array;
             return true;
         },
         (CycleDirection known) {
             turnNeeded = currentDir.knownValue == newDir ? 0 : 1;
             return false;
         }
     );

     if (err) return WaypointsOrError.errors(errRes);

Where DetectedCycleDir is defined as something like this:

     struct Timeout {}
     struct SelfCrossed {}
     struct Indifferent {}

     alias DetectedCycleDir = SumType!(
         Timeout,
         SelfCrossed,
         Indifferent,
         CycleDirection
     );

Of course, this is only looking at a single fragment in 
isolation. With knowledge of the full function this is taken 
from, it would probably be possible to come up with a more 
elegant way of refactoring it--perhaps by using an `Optional` or 
`Result` type, or by splitting the parts before and after the 
early return into independent functions.


More information about the Digitalmars-d mailing list