First Draft: Nominal Sum Types via `enum union` and `switch` Expressions
Dukc
ajieskola at gmail.com
Mon Sep 28 14:48:09 UTC 2026
On Sunday, 27 September 2026 at 09:28:42 UTC, Meta wrote:
>> ```d
>> // omitting template constraint
>> alias HavingValue(T, bool having : true) = T.just;
>> alias HavingValue(T, bool having : false) = T.nothing;
>>
>> alias OurType = typeof(someOptionalInt);
>> auto someVar = switch(someOptionalInt)
>> { case HavingValue!(OurType, true)(theInt) => text("int
>> value ", theInt),
>> case HavingValue!(OurType, false) => "no value, nothing to
>> see",
>> }
>> ```
>
> Ah, no, that's not supported.
You're going to want this when you're pattern matching over a
templated type. It could be something like:
```d
Exception extractException(T)(T value) => switch(value)
{ case ErrorCaseOf!T(string msg) =>
new Exception(msg),
default => null
}
```
>
>>> A default arm allows you to omit any number of other cases.
>>> The problem is, how do you unify the types of the omitted
>>> cases when they can easily all be invariant with each-other?
>>> What is the type of `v` within the type system?
>>
>> If we follow OCaml and Haskell, it'd be `U`.
>
> That is only possible because the variants in Haskell and OCaml
> are data constructors, not types. In the general case, it's not
> possible.
I'm not sure we're talking about the same thing. You yourself
wrote that the same can be done with `auto` declaration in place
of the switched-on expression. Why wouldn't a `case v => ...` or
`default v => ...` syntax be possible given it does the same
thing?
>> So pretty much how I first proposed wildcards act. I don't
>> currently have preference whether wildcards should work that
>> way, the Haskell/OCaml way, or something in-between way. You
>> DIP doesn't even have to decide that, assuming you're leaving
>> wildcards for another DIP. I just want to have the syntax
>> reserved for it, however it'll eventually work.
>
> There's no point to it, as I showed in my other post. You
> always have access to the value that's being switched on, so a
> default case with an identifier is redundant.
I admit if it was about top-level wildcards _only_, it would be a
somewhat redundant feature. But, in a sense you are already
partially supporting Haskell/OCaml - style wildcards. In fact,
they are the only way you can currently handle a case with a
parameter, such as `case int`. Haskell and OCaml allow, and D
will likely some day allow to alternatively pattern match that
against subcases, int literals in this case.
Since the parameters in the cases are presumably going to support
both subcases and wildcard variables, it is only consistent to
have both cases and wildcard variables available at the top
level, and with the same syntax. It's called _pattern_ matching
for a reason.
More information about the dip.development
mailing list