First Draft: Nominal Sum Types via `enum union` and `switch` Expressions
Meta
jared771 at gmail.com
Thu Sep 24 00:21:53 UTC 2026
On Wednesday, 23 September 2026 at 22:23:46 UTC, Meta wrote:
> That can be simplified to:
> ```d
> enum union DynamicNumber
> {
> case long, float, double, error(string);
> }
>
> DynamicNumber sum(DynamicNumber a, DynamicNumber b) @safe
> {
> enum isBare(alias V) = __traits(variantKind, V) == "bare";
> alias NumericVariants = Filter!(isBare,
> __traits(allVariants, DynamicNumber));
> return switch (a)
> {
> case error => a,
> static foreach (V1; NumericVariants)
> case V1 v1 => switch (b)
> {
> case error => b,
> static foreach (V2; NumericVariants)
> case V2 v2 => DynamicNumber(v1 + v2),
> },
> };
> }
> ```
>
> Actually that's pretty straightforward for a fairly complex
> case. The only thing that's needed is static foreach support
> for generating switch arms, which is on my todo list already.
And it's now implemented:
```d
enum union Shape
{
case Circle(double);
case Rect(double, double);
case Point();
}
double area(Shape s)
{
return switch (s)
{
static foreach (T; __traits(allVariants, Shape))
{
static if (__traits(identifier, T) == "Circle")
{
case Circle(r) => 3.14159 * r * r,
}
else static if (__traits(identifier, T) == "Rect")
{
case Rect(w, h) => w * h,
}
else
{
// Optional trailing delimiter before right curly
case Point() => 0.0
}
}
};
}
Shape sh = Shape.Rect(3.0, 4.0);
assert(area(sh) == 12.0);
```
More information about the dip.development
mailing list