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