First Draft: Nominal Sum Types via `enum union` and `switch` Expressions
Meta
jared771 at gmail.com
Sun Sep 27 09:28:42 UTC 2026
On Saturday, 26 September 2026 at 21:31:36 UTC, Dukc wrote:
> On Saturday, 26 September 2026 at 00:47:37 UTC, Meta wrote:
>> I don't know what you mean by template instances in this case.
>> Are you talking about this?
>> ```d
>> struct S(T);
>> enum union E(T) { case S!T; }
>>
>> switch(...)
>> {
>> case S!T, T => writeln(T.stringof)
>> }
>> ```
>
> No, I mean things like this:
>
> ```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.
>>>
>>> Had another look how OCaml does it. It does support
>>> wildcards, but they do not work as I proposed. Instead, they
>>> are essentially `default` cases with a variable name, the
>>> variable binding to result of the matched expression. I think
>>> that's a good alternative.
>>
>> The problem with that is:
>> ```d
>> enum union U { case int, string, bool, Unit() }
>>
>> switch(U.init)
>> {
>> default v => ...
>> }
>> ```
>>
>> 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.
>>
>> Rikki did include this in his DIP, and his solution was that
>> it acts like a template lambda or a static foreach loop. The
>> arm is duplicated automatically by the compiler for each type.
>
> 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.
More information about the dip.development
mailing list